-
Notifications
You must be signed in to change notification settings - Fork 1
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
Showing
19 changed files
with
981 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# mackerelstatsd | ||
|
||
Statsd server for Mackerel. |
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,46 @@ | ||
package cactusstatsd | ||
|
||
import ( | ||
"time" | ||
|
||
"github.com/cactus/go-statsd-client/v5/statsd" | ||
|
||
proto "github.com/hatena/mackerelstatsd/statsd" | ||
) | ||
|
||
type Driver struct { | ||
c statsd.Statter | ||
} | ||
|
||
var _ proto.Driver = (*Driver)(nil) | ||
|
||
func NewDriver(addr, prefix string) (*Driver, error) { | ||
c, err := statsd.NewClientWithConfig(&statsd.ClientConfig{ | ||
Address: addr, | ||
Prefix: prefix, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &Driver{c: c}, nil | ||
} | ||
|
||
func (d *Driver) Inc(name string, n int64, rate float64, tags []*proto.Tag) error { | ||
rawTags := make([]statsd.Tag, len(tags)) | ||
for i, tag := range tags { | ||
rawTags[i] = statsd.Tag{tag.Key, tag.Value} | ||
} | ||
return d.c.Inc(name, n, float32(rate), rawTags...) | ||
} | ||
|
||
func (d *Driver) Timer(name string, dur time.Duration, rate float64, tags []*proto.Tag) error { | ||
rawTags := make([]statsd.Tag, len(tags)) | ||
for i, tag := range tags { | ||
rawTags[i] = statsd.Tag{tag.Key, tag.Value} | ||
} | ||
return d.c.TimingDuration(name, dur, float32(rate), rawTags...) | ||
} | ||
|
||
func (d *Driver) Close() error { | ||
return d.c.Close() | ||
} |
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,25 @@ | ||
package middleware | ||
|
||
import ( | ||
"net/http" | ||
"strings" | ||
"time" | ||
|
||
"github.com/hatena/mackerelstatsd/metricname" | ||
"github.com/hatena/mackerelstatsd/statsd" | ||
) | ||
|
||
func metricName(path string) string { | ||
name := strings.ReplaceAll(path, "/", "_") | ||
return name | ||
} | ||
|
||
func HTTPHandler(next http.Handler, c *statsd.Client) http.Handler { | ||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
start := time.Now() | ||
next.ServeHTTP(w, r) | ||
delta := time.Since(start) | ||
name := metricname.Join("http.request" + metricName(r.URL.Path)) | ||
c.Timer(name, delta, &statsd.Options{SamplingRate: 1.0}) | ||
}) | ||
} |
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,59 @@ | ||
package main | ||
|
||
import ( | ||
"io" | ||
"log" | ||
"math/rand" | ||
"net/http" | ||
"sync" | ||
"time" | ||
|
||
"github.com/hatena/mackerelstatsd/example/driver/cactusstatsd" | ||
"github.com/hatena/mackerelstatsd/statsd" | ||
) | ||
|
||
func main() { | ||
log.SetFlags(0) | ||
d, err := cactusstatsd.NewDriver("localhost:8125", "custom.statsd.sample") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
c := statsd.NewClient(d) | ||
defer c.Close() | ||
|
||
var wg sync.WaitGroup | ||
|
||
wg.Add(1) | ||
go func() { | ||
for i := 0; i < 10; i++ { | ||
n := rand.Int63n(6) + 1 | ||
if err := c.Inc("dice", n, &statsd.Options{SamplingRate: 1.0}); err != nil { | ||
log.Fatal(err) | ||
} | ||
time.Sleep(1 * time.Second) | ||
} | ||
wg.Done() | ||
}() | ||
|
||
wg.Add(1) | ||
go func() { | ||
for i := 0; i < 10; i++ { | ||
start := time.Now() | ||
resp, err := http.Get("https://hatena.co.jp/") | ||
if err != nil { | ||
time.Sleep(2 * time.Second) | ||
continue | ||
} | ||
io.Copy(io.Discard, resp.Body) | ||
d := time.Since(start) | ||
if err := c.Timer("http.hatena", d, &statsd.Options{SamplingRate: 1.0}); err != nil { | ||
log.Fatal(err) | ||
} | ||
resp.Body.Close() | ||
time.Sleep(2 * time.Second) | ||
} | ||
wg.Done() | ||
}() | ||
|
||
wg.Wait() | ||
} |
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,26 @@ | ||
package main | ||
|
||
import ( | ||
"io" | ||
"log" | ||
"net/http" | ||
|
||
"github.com/hatena/mackerelstatsd/example/driver/cactusstatsd" | ||
"github.com/hatena/mackerelstatsd/example/middleware" | ||
"github.com/hatena/mackerelstatsd/statsd" | ||
) | ||
|
||
func helloHandler(w http.ResponseWriter, req *http.Request) { | ||
io.WriteString(w, "Hello, world!\n") | ||
} | ||
|
||
func main() { | ||
d, err := cactusstatsd.NewDriver("localhost:8125", "custom.statsd.sample") | ||
if err != nil { | ||
log.Fatal(err) | ||
} | ||
c := statsd.NewClient(d) | ||
defer c.Close() | ||
http.Handle("/", middleware.HTTPHandler(http.HandlerFunc(helloHandler), c)) | ||
log.Fatal(http.ListenAndServe(":8080", nil)) | ||
} |
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,11 @@ | ||
[Unit] | ||
Description=mackerelstatsd | ||
Documentation=https://mackerel.io/ | ||
After=network.target | ||
|
||
[Service] | ||
EnvironmentFile=-/etc/sysconfig/mackerelstatsd | ||
ExecStart=/usr/local/bin/mackerelstatsd -host $HOSTID $OTHER_OPTS | ||
|
||
[Install] | ||
WantedBy=multi-user.target |
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,3 @@ | ||
# /etc/sysconfig/mackerelstatsd | ||
MACKEREL_APIKEY=__YOUR_MACKEREL_APIKEY__ | ||
HOSTID=__YOUR_HOSTID__ |
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,33 @@ | ||
package main | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/mackerelio/mackerel-client-go" | ||
) | ||
|
||
type mackerelClientMock struct { | ||
postHostMetricCalledNum int | ||
} | ||
|
||
func (c *mackerelClientMock) PostHostMetricValuesByHostID(hostID string, values []*mackerel.MetricValue) error { | ||
c.postHostMetricCalledNum++ | ||
return nil | ||
} | ||
|
||
func (c *mackerelClientMock) CreateGraphDefs(params []*mackerel.GraphDefsParam) error { | ||
return nil | ||
} | ||
|
||
func TestExporterExportMetricsEmpty(t *testing.T) { | ||
var e Exporter | ||
s := NewSink() | ||
var c mackerelClientMock | ||
err := e.ExportMetrics(s, "xxx", &c) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
if c.postHostMetricCalledNum != 0 { | ||
t.Errorf("PostHostMetric should not be called, but it called %d times", c.postHostMetricCalledNum) | ||
} | ||
} |
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,13 @@ | ||
module github.com/hatena/mackerelstatsd | ||
|
||
go 1.19 | ||
|
||
require ( | ||
github.com/cactus/go-statsd-client/v5 v5.0.0 | ||
github.com/mackerelio/mackerel-client-go v0.23.0 | ||
) | ||
|
||
require ( | ||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect | ||
golang.org/x/tools v0.0.0-20200612022331-742c5eb664c2 // indirect | ||
) |
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,28 @@ | ||
github.com/cactus/go-statsd-client/v5 v5.0.0 h1:KqvIQtc9qt34uq+nu4nd1PwingWfBt/IISgtUQ2nSJk= | ||
github.com/cactus/go-statsd-client/v5 v5.0.0/go.mod h1:COEvJ1E+/E2L4q6QE5CkjWPi4eeDw9maJBMIuMPBZbY= | ||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= | ||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= | ||
github.com/mackerelio/mackerel-client-go v0.23.0 h1:C6ENbhfAZWofpr2Vc/cRTNdCkQonQ/nRlA08K+9+m/M= | ||
github.com/mackerelio/mackerel-client-go v0.23.0/go.mod h1:VM9KAjzs7wkROQ9WdZRvkY8K/bIUllN82dxyK36ZU3s= | ||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= | ||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k= | ||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= | ||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= | ||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= | ||
golang.org/x/tools v0.0.0-20200612022331-742c5eb664c2 h1:DVqHa33CzfnTKwUV6be+I4hp31W6iXn3ZiEcdKGzLyI= | ||
golang.org/x/tools v0.0.0-20200612022331-742c5eb664c2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= | ||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
Oops, something went wrong.