aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <ms@kilabit.info>2023-04-01 15:34:34 +0700
committerShulhan <ms@kilabit.info>2023-07-27 00:40:14 +0700
commita91993b95c88cf489e2503b6c8c03cbd7e67e207 (patch)
tree7b7679cbaf3e5d7226ead6a9f1678a0c28dc69fc
parent631dd476ac3fd7d7c8045b6e6ca59b63955bca67 (diff)
downloadrescached-dev-telemetry.tar.xz
[wip] cmd/rescached: add telemetry using questdbdev-telemetry
The telemetry collect the Go runtime/metrics and forward it to questdb instance in localhost.
-rw-r--r--_test/etc/rescached/rescached.cfg1
-rw-r--r--cmd/rescached/main.go92
-rw-r--r--environment.go6
-rw-r--r--environment_test.go1
-rw-r--r--go.mod13
-rw-r--r--go.sum22
-rw-r--r--testdata/rescached.cfg.test.out2
7 files changed, 124 insertions, 13 deletions
diff --git a/_test/etc/rescached/rescached.cfg b/_test/etc/rescached/rescached.cfg
index fd11806..9c406d6 100644
--- a/_test/etc/rescached/rescached.cfg
+++ b/_test/etc/rescached/rescached.cfg
@@ -11,6 +11,7 @@
file.resolvconf=
debug=1
wui.listen = 127.0.0.1:5381
+telemetry = questdb+tcp://127.0.0.1:9009
[block.d "a.block"]
name = a.block
diff --git a/cmd/rescached/main.go b/cmd/rescached/main.go
index e94be5e..1958974 100644
--- a/cmd/rescached/main.go
+++ b/cmd/rescached/main.go
@@ -13,8 +13,10 @@ import (
"flag"
"fmt"
"log"
+ "net/url"
"os"
"os/signal"
+ "regexp"
"strings"
"syscall"
"time"
@@ -22,6 +24,7 @@ import (
"git.sr.ht/~shulhan/ciigo"
"github.com/shuLhan/share/lib/debug"
"github.com/shuLhan/share/lib/memfs"
+ "github.com/shuLhan/share/lib/telemetry"
"github.com/shuLhan/rescached-go/v4"
)
@@ -85,6 +88,12 @@ func main() {
go debugRuntime()
}
+ var telemetryAgent *telemetry.Agent
+ telemetryAgent, err = createTelemetryAgent(env.Telemetry)
+ if err != nil {
+ log.Print(err)
+ }
+
qsignal = make(chan os.Signal, 1)
signal.Notify(qsignal, syscall.SIGQUIT, syscall.SIGSEGV, syscall.SIGTERM, syscall.SIGINT)
<-qsignal
@@ -92,6 +101,9 @@ func main() {
running <- false
<-running
}
+ if telemetryAgent != nil {
+ telemetryAgent.Stop()
+ }
rcd.Stop()
os.Exit(0)
}
@@ -111,6 +123,86 @@ func debugRuntime() {
}
}
+func createTelemetryAgent(telemetryOpt string) (agent *telemetry.Agent, err error) {
+ if len(telemetryOpt) == 0 {
+ return nil, nil
+ }
+
+ var (
+ logp = `createTelemetryAgent`
+ ilpFmt = telemetry.NewIlpFormatter(`rescached`)
+
+ forwarders []telemetry.Forwarder
+ telUrl *url.URL
+ )
+
+ telUrl, err = url.Parse(telemetryOpt)
+ if err != nil {
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
+ }
+
+ var schemes = strings.SplitN(telUrl.Scheme, `+`, 2)
+
+ switch schemes[0] {
+ case `questdb`:
+ telUrl.Scheme = schemes[1]
+
+ var (
+ qdbOpts = telemetry.QuestdbOptions{
+ Fmt: ilpFmt,
+ ServerUrl: telUrl.String(),
+ }
+
+ qdbFwd *telemetry.QuestdbForwarder
+ )
+
+ qdbFwd, err = telemetry.NewQuestdbForwarder(qdbOpts)
+ if err != nil {
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
+ }
+
+ log.Printf(`Starting telemetry using questdb: %s`, qdbOpts.ServerUrl)
+
+ forwarders = append(forwarders, qdbFwd)
+
+ default:
+ return nil, fmt.Errorf(`%s: unknown forwarder %s`, logp, schemes[0])
+ }
+
+ // Create metadata.
+ var md = telemetry.NewMetadata()
+ md.Set(`version`, rescached.Version)
+
+ var metricsCol telemetry.Collector
+ metricsCol, err = createMetricsCollector()
+ if err != nil {
+ return nil, fmt.Errorf(`%s: %w`, logp, err)
+ }
+
+ // Create the Agent.
+ var agentOpts = telemetry.AgentOptions{
+ Metadata: md,
+ Forwarders: forwarders,
+ Collectors: []telemetry.Collector{
+ metricsCol,
+ },
+ Interval: 10 * time.Second,
+ }
+
+ agent = telemetry.NewAgent(agentOpts)
+ return agent, nil
+}
+
+func createMetricsCollector() (col *telemetry.GoMetricsCollector, err error) {
+ var metricsFilter *regexp.Regexp
+ metricsFilter, err = regexp.Compile(`^go_(cpu|gc|memory|sched)_.*$`)
+ if err != nil {
+ return nil, err
+ }
+ col = telemetry.NewGoMetricsCollector(metricsFilter)
+ return col, nil
+}
+
// watchWww watch any changes to files inside _www directory and regenerate
// the embed file "memfs_generate.go".
func watchWww(env *rescached.Environment, running chan bool) {
diff --git a/environment.go b/environment.go
index 1068ea9..85e584a 100644
--- a/environment.go
+++ b/environment.go
@@ -73,6 +73,12 @@ type Environment struct {
FileResolvConf string `ini:"rescached::file.resolvconf"`
WUIListen string `ini:"rescached::wui.listen"`
+ // Telemetry define the URI for sending telemetry.
+ // Format: "<forwarder>+<url>".
+ // For example, collecting telemetry to store in questdb at localhost,
+ // "questdb+tcp://127.0.0.1:9009"
+ Telemetry string `ini:"rescached::telemetry"`
+
HostBlockd map[string]*Blockd `ini:"block.d"`
hostBlockdFile map[string]*dns.HostsFile
hostsd map[string]*dns.HostsFile
diff --git a/environment_test.go b/environment_test.go
index 467bd5b..0f1ffdc 100644
--- a/environment_test.go
+++ b/environment_test.go
@@ -73,6 +73,7 @@ func TestLoadEnvironment(t *testing.T) {
fileConfig: filepath.Join(testDirBase, "/etc/rescached/rescached.cfg"),
WUIListen: "127.0.0.1:5381",
+ Telemetry: `questdb+tcp://127.0.0.1:9009`,
HostBlockd: map[string]*Blockd{
"a.block": &Blockd{
Name: "a.block",
diff --git a/go.mod b/go.mod
index 11a5865..82bbc84 100644
--- a/go.mod
+++ b/go.mod
@@ -6,14 +6,17 @@ module github.com/shuLhan/rescached-go/v4
go 1.19
require (
- git.sr.ht/~shulhan/ciigo v0.9.3
- github.com/shuLhan/share v0.45.0
+ git.sr.ht/~shulhan/ciigo v0.10.0
+ github.com/shuLhan/share v0.46.0
)
require (
git.sr.ht/~shulhan/asciidoctor-go v0.4.1 // indirect
- golang.org/x/net v0.7.0 // indirect
- golang.org/x/sys v0.5.0 // indirect
+ github.com/yuin/goldmark v1.5.4 // indirect
+ github.com/yuin/goldmark-meta v1.1.0 // indirect
+ golang.org/x/net v0.12.0 // indirect
+ golang.org/x/sys v0.10.0 // indirect
+ gopkg.in/yaml.v2 v2.3.0 // indirect
)
-//replace github.com/shuLhan/share => ../share
+replace github.com/shuLhan/share => ../share
diff --git a/go.sum b/go.sum
index 809c93e..9fc748c 100644
--- a/go.sum
+++ b/go.sum
@@ -1,10 +1,16 @@
git.sr.ht/~shulhan/asciidoctor-go v0.4.1 h1:Zev0L5HyMjH43sPaoJal8E/Hmbel/akoGOxNykhN4Dw=
git.sr.ht/~shulhan/asciidoctor-go v0.4.1/go.mod h1:vRHDUl3o3UzDkvVR9dEFYQ0JDqOh0TKpOZWvOh/CGZU=
-git.sr.ht/~shulhan/ciigo v0.9.3 h1:q6EqGVvIU8ymkPqBS4HEyHIhbfVhJn6urwvGDg83TAY=
-git.sr.ht/~shulhan/ciigo v0.9.3/go.mod h1:SsRnbqnBo+9jWDDZD/uc9IkdgGpBfp39vV0JPXNro9c=
-github.com/shuLhan/share v0.45.0 h1:3uCGNtgWy9mta6re61ayMVp7WICNMtBUvHwtUBVTgZw=
-github.com/shuLhan/share v0.45.0/go.mod h1:BhnIWJxq84BTOs3Z2gLFAN8ih9mBfhZbRIjqGupGJag=
-golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+git.sr.ht/~shulhan/ciigo v0.10.0 h1:s1SJ3/NzBcbOLmEZ4z1Cx9Vf7ZdDIvm45b7KMCZKzEY=
+git.sr.ht/~shulhan/ciigo v0.10.0/go.mod h1:cG6av+ywJZZp96F43kmLB2QWjm2hYiahbsbeTX/vlgk=
+github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU=
+github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yuin/goldmark-meta v1.1.0 h1:pWw+JLHGZe8Rk0EGsMVssiNb/AaPMHfSRszZeUeiOUc=
+github.com/yuin/goldmark-meta v1.1.0/go.mod h1:U4spWENafuA7Zyg+Lj5RqK/MF+ovMYtBvXi1lBb2VP0=
+golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
+golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
+golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
+golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
+gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/testdata/rescached.cfg.test.out b/testdata/rescached.cfg.test.out
index 8f36010..a31a1d6 100644
--- a/testdata/rescached.cfg.test.out
+++ b/testdata/rescached.cfg.test.out
@@ -1,6 +1,7 @@
[rescached]
file.resolvconf =
wui.listen = 127.0.0.1:5381
+telemetry = questdb+tcp://127.0.0.1:9009
debug = 1
[block.d "a.block"]
@@ -27,6 +28,7 @@ parent = udp://10.8.0.1
http.idle_timeout = 0s
cache.prune_delay = 0s
cache.prune_threshold = 0s
+debug = 0
http.port = 0
tls.port = 0
tls.allow_insecure = true