forked from grafana/groupcache_exporter
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
udhos
committed
Feb 1, 2024
1 parent
ffe4c89
commit 85dea63
Showing
8 changed files
with
253 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |