storj/pkg/process/process.go
JT Olio 22b1fe4e21 pkg/process: add pkg/telemetry plumbing (#47)
* pkg/process: add pkg/telemetry plumbing

* pkg/process: add debug endpoints

* fix linting
2018-05-30 10:03:44 -04:00

98 lines
2.1 KiB
Go

// Copyright (C) 2018 Storj Labs, Inc.
// See LICENSE for copying information.
package process
import (
"context"
"flag"
"log"
"github.com/spacemonkeygo/flagfile"
"github.com/zeebo/errs"
"go.uber.org/zap"
monkit "gopkg.in/spacemonkeygo/monkit.v2"
"storj.io/storj/pkg/telemetry"
"storj.io/storj/pkg/utils"
)
var (
logDisposition = flag.String("log.disp", "prod",
"switch to 'dev' to get more output")
// Error is a process error class
Error = errs.Class("ProcessError")
)
// ID is the type used to specify a ID key in the process context
type ID string
// Service defines the interface contract for all Storj services
type Service interface {
// Process should run the program
Process(context.Context) error
SetLogger(*zap.Logger) error
SetMetricHandler(*monkit.Registry) error
// InstanceID should return a server or process instance identifier that is
// stable across restarts, or the empty string to use the first non-nil
// MAC address
InstanceID() string
}
const (
id ID = "SrvID"
)
// Main initializes a new Service
func Main(s Service) (err error) {
flagfile.Load()
ctx := context.Background()
instanceID := s.InstanceID()
if instanceID == "" {
instanceID = telemetry.DefaultInstanceID()
}
ctx, cf := context.WithCancel(context.WithValue(ctx, id, instanceID))
defer cf()
registry := monkit.Default
scope := registry.ScopeNamed("process")
defer scope.TaskNamed("main")(&ctx)(&err)
logger, err := utils.NewLogger(*logDisposition,
zap.Fields(zap.String(string(id), instanceID)))
if err != nil {
return err
}
defer logger.Sync()
defer zap.ReplaceGlobals(logger)()
defer zap.RedirectStdLog(logger)()
s.SetLogger(logger)
s.SetMetricHandler(registry)
err = initMetrics(ctx, registry, instanceID)
if err != nil {
logger.Error("failed to configure telemetry", zap.Error(err))
}
err = initDebug(ctx, logger, registry)
if err != nil {
logger.Error("failed to start debug endpoints", zap.Error(err))
}
return s.Process(ctx)
}
// Must can be used for default Main error handling
func Must(err error) {
if err != nil {
log.Fatal(err)
}
}