storj/pkg/process/metrics.go
JT Olio 8c57434ded
pkg/process/metrics: add an instance prefix (#2190)
* pkg/process/metrics: add an instance prefix

the distinction between which satellite is sending which
data should go in the instance field, not the suffix or application
fields. (un)fortunately, the instance id is deliberately not
configurable because we don't want it to be easy to accidentally
have multiple applications collide with the same instance id.

so we're currently stuffing the human readable instance in the
suffix. :(

perhaps a reasonable tradeoff would be an optional instance
prefix that allows operators to put their domain name in
the instance

Change-Id: I6fcc8498be908c5740439cc00f77474ad151febd

* linting

Change-Id: I9f9a44fa9a2634ef5e4f89548d42d57ce9e4450e
2019-06-24 16:45:37 -06:00

89 lines
2.7 KiB
Go

// Copyright (C) 2019 Storj Labs, Inc.
// See LICENSE for copying information.
package process
import (
"context"
"flag"
"os"
"path/filepath"
hw "github.com/jtolds/monkit-hw"
"github.com/zeebo/admission/admproto"
"go.uber.org/zap"
monkit "gopkg.in/spacemonkeygo/monkit.v2"
"gopkg.in/spacemonkeygo/monkit.v2/environment"
"storj.io/storj/internal/version"
"storj.io/storj/pkg/cfgstruct"
"storj.io/storj/pkg/identity"
"storj.io/storj/pkg/telemetry"
)
var (
metricInterval = flag.Duration("metrics.interval", telemetry.DefaultInterval, "how frequently to send up telemetry")
metricCollector = flag.String("metrics.addr", flagDefault("", "collectora.storj.io:9000"), "address to send telemetry to")
metricApp = flag.String("metrics.app", filepath.Base(os.Args[0]), "application name for telemetry identification")
metricAppSuffix = flag.String("metrics.app-suffix", flagDefault("-dev", "-release"), "application suffix")
metricInstancePrefix = flag.String("metrics.instance-prefix", "", "instance id prefix")
)
const (
maxInstanceLength = 52
)
func flagDefault(dev, release string) string {
if cfgstruct.DefaultsType() == "release" {
return release
}
return dev
}
// InitMetrics initializes telemetry reporting. Makes a telemetry.Client and calls
// its Run() method in a goroutine.
func InitMetrics(ctx context.Context, r *monkit.Registry, instanceID string) (err error) {
if *metricCollector == "" || *metricInterval == 0 {
return Error.New("telemetry disabled")
}
if r == nil {
r = monkit.Default
}
if instanceID == "" {
instanceID = telemetry.DefaultInstanceID()
}
instanceID = *metricInstancePrefix + instanceID
if len(instanceID) > maxInstanceLength {
instanceID = instanceID[:maxInstanceLength]
}
c, err := telemetry.NewClient(*metricCollector, telemetry.ClientOpts{
Interval: *metricInterval,
Application: *metricApp + *metricAppSuffix,
Instance: instanceID,
Registry: r,
FloatEncoding: admproto.Float32Encoding,
})
if err != nil {
return err
}
environment.Register(r)
hw.Register(r)
r.ScopeNamed("env").Chain("version", monkit.StatSourceFunc(version.Build.Stats))
go c.Run(ctx)
return nil
}
// InitMetricsWithCertPath initializes telemetry reporting, using the node ID
// corresponding to the given certificate as the telemetry instance ID.
func InitMetricsWithCertPath(ctx context.Context, r *monkit.Registry, certPath string) error {
var metricsID string
nodeID, err := identity.NodeIDFromCertPath(certPath)
if err != nil {
zap.S().Errorf("Could not read identity for telemetry setup: %v", err)
metricsID = "" // InitMetrics() will fill in a default value
} else {
metricsID = nodeID.String()
}
return InitMetrics(ctx, r, metricsID)
}