Skip to content

Commit

Permalink
Support google groupcache.
Browse files Browse the repository at this point in the history
  • Loading branch information
udhos committed Feb 1, 2024
1 parent ffe4c89 commit 85dea63
Show file tree
Hide file tree
Showing 8 changed files with 253 additions and 28 deletions.
2 changes: 2 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/bin/bash

go install golang.org/x/vuln/cmd/govulncheck@latest
go install golang.org/x/tools/cmd/deadcode@latest

gofmt -s -w .

Expand All @@ -11,6 +12,7 @@ gocyclo -over 15 .
go mod tidy

govulncheck ./...
deadcode ./examples/*

go env -w CGO_ENABLED=1

Expand Down
63 changes: 63 additions & 0 deletions examples/groupcache-exporter-google/groupcache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package main

import (
"context"
"log"
"net/http"
"os"

"github.com/golang/groupcache"
)

func startGroupcache() *groupcache.Group {

//
// create groupcache pool
//

groupcachePort := ":5000"

myURL := "http:https://127.0.0.1" + groupcachePort

log.Printf("groupcache my URL: %s", myURL)

pool := groupcache.NewHTTPPoolOpts(myURL, &groupcache.HTTPPoolOptions{})

//
// start groupcache server
//

serverGroupCache := &http.Server{Addr: groupcachePort, Handler: pool}

go func() {
log.Printf("groupcache server: listening on %s", groupcachePort)
err := serverGroupCache.ListenAndServe()
log.Printf("groupcache server: exited: %v", err)
}()

pool.Set(myURL)

//
// create cache
//

var groupcacheSizeBytes int64 = 1_000_000

// https://talks.golang.org/2013/oscon-dl.slide#46
//
// 64 MB max per-node memory usage
cache := groupcache.NewGroup("files", groupcacheSizeBytes, groupcache.GetterFunc(
func(ctx context.Context, key string, dest groupcache.Sink) error {

log.Printf("getter: loading: key:%s", key)

data, errFile := os.ReadFile(key)
if errFile != nil {
return errFile
}

return dest.SetBytes(data)
}))

return cache
}
62 changes: 62 additions & 0 deletions examples/groupcache-exporter-google/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Package main implements the example.
package main

import (
"context"
"log"
"net/http"
"os"
"path/filepath"
"time"

"github.com/golang/groupcache"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/udhos/groupcache_exporter"
"github.com/udhos/groupcache_exporter/groupcache/google"
)

func main() {

appName := filepath.Base(os.Args[0])

cache := startGroupcache()

//
// expose prometheus metrics
//
{
metricsRoute := "/metrics"
metricsPort := ":3000"

log.Printf("starting metrics server at: %s %s", metricsPort, metricsRoute)

google := google.New(cache)
labels := map[string]string{
"app": appName,
}
namespace := ""
collector := groupcache_exporter.NewExporter(namespace, labels, google)

prometheus.MustRegister(collector)

go func() {
http.Handle(metricsRoute, promhttp.Handler())
log.Fatal(http.ListenAndServe(metricsPort, nil))
}()
}

//
// query cache periodically
//

const interval = 5 * time.Second

for {
var dst []byte
cache.Get(context.TODO(), "/etc/passwd", groupcache.AllocatingByteSliceSink(&dst))
log.Printf("cache answer: %d bytes, sleeping %v", len(dst), interval)
time.Sleep(interval)
}

}
4 changes: 1 addition & 3 deletions examples/groupcache-exporter-mailgun/groupcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ func startGroupcache() *groupcache.Group {
}

expire := time.Now().Add(ttl)
dest.SetBytes(data, expire)

return nil
return dest.SetBytes(data, expire)
}))

return cache
Expand Down
4 changes: 1 addition & 3 deletions examples/groupcache-exporter-modernprogram/groupcache.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ func startGroupcache() *groupcache.Group {
}

expire := time.Now().Add(ttl)
dest.SetBytes(data, expire)

return nil
return dest.SetBytes(data, expire)
}))

return cache
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/udhos/groupcache_exporter
go 1.21.6

require (
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da
github.com/mailgun/groupcache/v2 v2.5.0
github.com/modernprogram/groupcache/v2 v2.5.5
github.com/prometheus/client_golang v1.18.0
Expand Down
24 changes: 2 additions & 22 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,32 +1,22 @@
github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
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/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
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/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/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/mailgun/groupcache/v2 v2.5.0 h1:FoNR52GyTQ4jLoliSuyXDANMEoxts6M8ql9jW3htvq8=
github.com/mailgun/groupcache/v2 v2.5.0/go.mod h1:7+O6vXEKAhloSTOJOmkhyksS8l/gIs15fv0ER1ZuhPA=
github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/modernprogram/groupcache/v2 v2.5.5 h1:DfKTmO+9I6TmbelZEUEAUW6XBENrO1LAUV5SOw2b5SM=
github.com/modernprogram/groupcache/v2 v2.5.5/go.mod h1:lW+JZYFFe7HBd+9DH+hwEJyJEr6fiUfBbLmg/qQjS7A=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
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.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk=
Expand All @@ -37,7 +27,6 @@ github.com/prometheus/common v0.46.0 h1:doXzt5ybi1HBKpsZOL0sSkaNHJJqkyfEWZGGqqSc
github.com/prometheus/common v0.46.0/go.mod h1:Tp0qkxpb9Jsg54QMe+EAmqXkSV7Evdy1BTn+g2pa/hQ=
github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo=
github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/segmentio/fasthash v1.0.3 h1:EI9+KE1EwvMLBWwjpRDc+fEM+prwxDYbslddQGtrmhM=
github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KRMzBtS3oedY=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
Expand All @@ -46,24 +35,15 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
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.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
121 changes: 121 additions & 0 deletions groupcache/google/adapter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// Package google implements an adapter to extract metrics from google groupcache.
package google

import (
"github.com/golang/groupcache"
)

// Group implements interface GroupStatistics to extract metrics from google groupcache group.
type Group struct {
group *groupcache.Group
}

// New creates a new Group.
func New(group *groupcache.Group) *Group {
return &Group{group: group}
}

// Name returns the group's name
func (g *Group) Name() string {
return g.group.Name()
}

// Gets represents any Get request, including from peers
func (g *Group) Gets() int64 {
return g.group.Stats.Gets.Get()
}

// CacheHits represents either cache was good
func (g *Group) CacheHits() int64 {
return g.group.Stats.CacheHits.Get()
}

// GetFromPeersLatencyLower represents slowest duration to request value from peers
func (g *Group) GetFromPeersLatencyLower() int64 {
return 0
}

// PeerLoads represents either remote load or remote cache hit (not an error)
func (g *Group) PeerLoads() int64 {
return g.group.Stats.PeerLoads.Get()
}

// PeerErrors represents a count of errors from peers
func (g *Group) PeerErrors() int64 {
return g.group.Stats.PeerErrors.Get()
}

// Loads represents (gets - cacheHits)
func (g *Group) Loads() int64 {
return g.group.Stats.Loads.Get()
}

// LoadsDeduped represents after singleflight
func (g *Group) LoadsDeduped() int64 {
return g.group.Stats.LoadsDeduped.Get()
}

// LocalLoads represents total good local loads
func (g *Group) LocalLoads() int64 {
return g.group.Stats.LocalLoads.Get()
}

// LocalLoadErrs represents total bad local loads
func (g *Group) LocalLoadErrs() int64 {
return g.group.Stats.LocalLoadErrs.Get()
}

// ServerRequests represents gets that came over the network from peers
func (g *Group) ServerRequests() int64 {
return g.group.Stats.ServerRequests.Get()
}

// MainCacheItems represents number of items in the main cache
func (g *Group) MainCacheItems() int64 {
return g.group.CacheStats(groupcache.MainCache).Items
}

// MainCacheBytes represents number of bytes in the main cache
func (g *Group) MainCacheBytes() int64 {
return g.group.CacheStats(groupcache.MainCache).Bytes
}

// MainCacheGets represents number of get requests in the main cache
func (g *Group) MainCacheGets() int64 {
return g.group.CacheStats(groupcache.MainCache).Gets
}

// MainCacheHits represents number of hit in the main cache
func (g *Group) MainCacheHits() int64 {
return g.group.CacheStats(groupcache.MainCache).Hits
}

// MainCacheEvictions represents number of evictions in the main cache
func (g *Group) MainCacheEvictions() int64 {
return g.group.CacheStats(groupcache.MainCache).Evictions
}

// HotCacheItems represents number of items in the main cache
func (g *Group) HotCacheItems() int64 {
return g.group.CacheStats(groupcache.HotCache).Items
}

// HotCacheBytes represents number of bytes in the hot cache
func (g *Group) HotCacheBytes() int64 {
return g.group.CacheStats(groupcache.HotCache).Bytes
}

// HotCacheGets represents number of get requests in the hot cache
func (g *Group) HotCacheGets() int64 {
return g.group.CacheStats(groupcache.HotCache).Gets
}

// HotCacheHits represents number of hit in the hot cache
func (g *Group) HotCacheHits() int64 {
return g.group.CacheStats(groupcache.HotCache).Hits
}

// HotCacheEvictions represents number of evictions in the hot cache
func (g *Group) HotCacheEvictions() int64 {
return g.group.CacheStats(groupcache.HotCache).Evictions
}

0 comments on commit 85dea63

Please sign in to comment.