Skip to content

Export Prometheus telemetry in daemon mode #573

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 39 commits into from
Mar 10, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
ba172c3
Apply cosmetics
Jan 22, 2020
2c6634d
Implement ugly telemetry POC
Jan 23, 2020
11d1bdb
Added prefix and moved Insrumentation inside the command package
Jan 23, 2020
bb6a490
Refactor the telemetry module
Jan 24, 2020
18cdce8
Implement configuration via Viper
Jan 24, 2020
1262ba6
Add stats flush in case of a not daemonized cli daemon proces
Jan 24, 2020
a9d1b31
Add repertory to store installation id and secret
Jan 24, 2020
74fe852
Repertory force write
Jan 30, 2020
ab0a98c
Cosmetics
Jan 30, 2020
315cf00
Use viper config for repertory dir
Jan 30, 2020
b961a48
Add test for repertory file creation
Jan 30, 2020
e1ea063
Add testing for telemetry deaemon and repertory
Jan 30, 2020
30e7a2b
Wait for repertory and kill daemon
Jan 30, 2020
eb33588
Updated pyinvoke to use async feature to test the daemon
Jan 31, 2020
8974523
Updated daemon test timeout
Jan 31, 2020
e98c271
Cosmetics
Jan 31, 2020
ead55a3
Set getDefaultArduinoDataDir as unexported
Jan 31, 2020
216303f
Cosmetics
Jan 31, 2020
18481c0
Cosmetics
Jan 31, 2020
c448704
Cosmetics
Jan 31, 2020
0aea65c
Lint on repertory module
Jan 31, 2020
855b377
Set SIGTERM as kill signal in case of win platform to overcome pyinvo…
Feb 5, 2020
b203b7e
Import platform as a module
Feb 5, 2020
d0f448c
Reverse platform if for signal value
Feb 5, 2020
dc61b78
Extract pid value
Feb 5, 2020
040dc85
Remove print leftover
Mar 3, 2020
2d0808a
Add better error handling in repertory creation
Mar 5, 2020
b3bbdc6
Update docs with old README extract
Mar 5, 2020
90477d5
Remove telemetry.pattern setting from docs
Mar 5, 2020
4d5af7a
Remove serverPattern config option for telemetry
Mar 6, 2020
0fdc125
Upgrade viper to 1.6.2
Mar 6, 2020
965a70f
Defer stats Increment in compile command and explicit set for success…
Mar 6, 2020
e1582e7
Fix board list help message
Mar 6, 2020
ce6f4fa
Implement stats flush anyway to leverage module no-op in case of no h…
Mar 6, 2020
4e7b4cf
Rename "repertory" module in "inventory" and refactor Sanitize function
Mar 9, 2020
aaed29d
Sanitize ExportFile in command/compile
Mar 9, 2020
8b425a7
Refactor daemon start fixture to include daemon process cleanup
Mar 9, 2020
0625b39
Use defer function to push success tag correctly updated
Mar 9, 2020
3300d4d
Use named return parameters to handle success tagging for a command stat
Mar 10, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implement configuration via Viper
  • Loading branch information
Roberto Sora committed Mar 6, 2020
commit 18cdce8a2895f3dfc0d1f8390ec5a0c4130a07f5
7 changes: 4 additions & 3 deletions cli/daemon/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ var daemonize bool

func runDaemonCommand(cmd *cobra.Command, args []string) {

telemetry.Activate("daemon")
defer telemetry.Engine.Flush()
if viper.GetBool("telemetry.enabled") {
telemetry.Activate("daemon", viper.GetString("installation.id"))
defer telemetry.Engine.Flush()
}

port := viper.GetString("daemon.port")
s := grpc.NewServer()
Expand Down Expand Up @@ -99,7 +101,6 @@ func runDaemonCommand(cmd *cobra.Command, args []string) {
go func() {
// Stdin is closed when the controlling parent process ends
_, _ = io.Copy(ioutil.Discard, os.Stdin)
telemetry.Engine.Flush()
os.Exit(0)
}()
}
Expand Down
2 changes: 1 addition & 1 deletion commands/compile/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func Compile(ctx context.Context, req *rpc.CompileReq, outStream, errStream io.W

tags := map[string]string{
"fqbn": req.Fqbn,
"sketchPath": req.SketchPath,
"sketchPath": telemetry.SanitizeSketchPath(req.SketchPath),
"showProperties": strconv.FormatBool(req.ShowProperties),
"preprocess": strconv.FormatBool(req.Preprocess),
"buildProperties": strings.Join(req.BuildProperties, ","),
Expand Down
14 changes: 14 additions & 0 deletions configuration/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package configuration
import (
"path/filepath"

"github.com/gofrs/uuid"
"github.com/spf13/viper"
)

Expand All @@ -35,4 +36,17 @@ func setDefaults(dataDir, userDir string) {

// daemon settings
viper.SetDefault("daemon.port", "50051")

//telemetry settings
viper.SetDefault("telemetry.enabled", true)
viper.SetDefault("telemetry.addr", ":2112")
viper.SetDefault("telemetry.pattern", "/metrics")

//Installation ID
// FIXME: how should I treat this error?
installationID, _ := uuid.NewV4()
installationSecret, _ := uuid.NewV4()
viper.SetDefault("installation.id", installationID.String())
viper.SetDefault("installation.secret", installationSecret.String())

}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ require (
github.com/fluxio/multierror v0.0.0-20160419044231-9c68d39025e5 // indirect
github.com/fsnotify/fsnotify v1.4.7
github.com/go-errors/errors v1.0.1
github.com/gofrs/uuid v3.2.0+incompatible
github.com/golang/protobuf v1.3.3
github.com/h2non/filetype v1.0.8 // indirect
github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5 // indirect
Expand Down
6 changes: 5 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
Expand Down Expand Up @@ -113,8 +115,8 @@ github.com/schollz/closestmatch v2.1.0+incompatible h1:Uel2GXEpJqOWBrlyI+oY9LTiy
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
github.com/segmentio/fasthash v0.0.0-20180216231524-a72b379d632e h1:uO75wNGioszjmIzcY/tvdDYKRLVvzggtAmmJkn9j4GQ=
github.com/segmentio/fasthash v0.0.0-20180216231524-a72b379d632e/go.mod h1:tm/wZFQ8e24NYaBGIlnO2WGCAi67re4HHuOm0sftE/M=
github.com/segmentio/objconv v1.0.1 h1:QjfLzwriJj40JibCV3MGSEiAoXixbp4ybhwfTB8RXOM=
github.com/segmentio/objconv v1.0.1/go.mod h1:auayaH5k3137Cl4SoXTgrzQcuQDmvuVtZgS0fb1Ahys=
github.com/segmentio/stats v4.1.0+incompatible h1:Sz7ypAORgiXoR8x8VNIOKYoVpJUIeHGt/2UDMjjRFuo=
github.com/segmentio/stats/v4 v4.5.3 h1:Y/DSUWZ4c8ICgqJ9rQohzKvGqGWbLPWad5zmxVoKN+Y=
github.com/segmentio/stats/v4 v4.5.3/go.mod h1:LsaahUJR7iiSs8mnkvQvdQ/RLHAS5adGLxuntg0ydGo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
Expand Down Expand Up @@ -167,6 +169,7 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
Expand Down Expand Up @@ -213,6 +216,7 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce h1:xcEWjVhvbDy+nHP67nPDDpbYrY+ILlfndk4bRioVHaU=
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
38 changes: 27 additions & 11 deletions telemetry/telemetry.go
Original file line number Diff line number Diff line change
@@ -1,36 +1,52 @@
package telemetry

import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"net/http"
"path/filepath"

"github.com/segmentio/stats/v4"
"github.com/segmentio/stats/v4/prometheus"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
)

// Engine is the engine used by global helper functions for this module.
var Engine = stats.DefaultEngine

var serverAddr = ":2112"
var serverPattern = "/metrics"

//Activate configure and starts the telemetry server exposing a Prometheus resource
func Activate(metricPrefix string) {
// Activate configure and starts the telemetry server exposing a Prometheus resource
func Activate(metricPrefix, installationID string) {
// Configure telemetry engine
// Create a Prometheus default handler
ph := prometheus.DefaultHandler
// Replace the default stats engine with an engine that prepends the "daemon" prefix to all metrics
Engine = stats.WithPrefix(metricPrefix)
// Create a new stats engine with an engine that prepends the "daemon" prefix to all metrics
// and includes the installationID as a tag
Engine = stats.WithPrefix(metricPrefix, stats.T("installationID", installationID))
// Register the handler so it receives metrics from the default engine.
Engine.Register(ph)
// Flush the default stats engine on return to ensure all buffered
// metrics are sent to the server.
defer Engine.Flush()
// move everything inside commands and search for setting up a common prefix for all metrics sent!

// Configure using viper settings
serverAddr := viper.GetString("telemetry.addr")
serverPattern := viper.GetString("telemetry.pattern")
logrus.Infof("Setting up Prometheus telemetry on %s%s", serverAddr, serverPattern)
go func() {
http.Handle(serverPattern, ph)
logrus.Error(http.ListenAndServe(serverAddr, nil))
}()

}

// SanitizeSketchPath uses config generated UUID (installation.secret) as an HMAC secret to sanitize and anonymize the sketch
// name maintaining it distinguishable from a different sketch from the same Installation
func SanitizeSketchPath(sketchPath string) string {
installationSecret := viper.GetString("installation.secret")
sketchName := filepath.Base(sketchPath)
// Create a new HMAC by defining the hash type and the key (as byte array)
h := hmac.New(sha256.New, []byte(installationSecret))
// Write Data to it
h.Write([]byte(sketchName))
// Get result and encode as hexadecimal string
return hex.EncodeToString(h.Sum(nil))
}