2018-05-16 19:47:59 +01:00
|
|
|
// Copyright (C) 2018 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
|
|
|
package process
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"flag"
|
2018-05-30 15:03:44 +01:00
|
|
|
"log"
|
2018-05-16 19:47:59 +01:00
|
|
|
|
2018-05-30 15:03:44 +01:00
|
|
|
"github.com/spacemonkeygo/flagfile"
|
|
|
|
"github.com/zeebo/errs"
|
2018-05-16 19:47:59 +01:00
|
|
|
"go.uber.org/zap"
|
|
|
|
monkit "gopkg.in/spacemonkeygo/monkit.v2"
|
|
|
|
|
2018-05-30 15:03:44 +01:00
|
|
|
"storj.io/storj/pkg/telemetry"
|
2018-05-16 19:47:59 +01:00
|
|
|
"storj.io/storj/pkg/utils"
|
|
|
|
)
|
|
|
|
|
2018-05-30 15:03:44 +01:00
|
|
|
var (
|
|
|
|
logDisposition = flag.String("log.disp", "prod",
|
|
|
|
"switch to 'dev' to get more output")
|
|
|
|
|
|
|
|
// Error is a process error class
|
|
|
|
Error = errs.Class("ProcessError")
|
|
|
|
)
|
|
|
|
|
2018-05-16 19:47:59 +01:00
|
|
|
// 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 {
|
2018-05-30 15:03:44 +01:00
|
|
|
// Process should run the program
|
2018-05-16 19:47:59 +01:00
|
|
|
Process(context.Context) error
|
2018-05-30 15:03:44 +01:00
|
|
|
|
2018-05-16 19:47:59 +01:00
|
|
|
SetLogger(*zap.Logger) error
|
|
|
|
SetMetricHandler(*monkit.Registry) error
|
2018-05-30 15:03:44 +01:00
|
|
|
|
|
|
|
// 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
|
2018-05-16 19:47:59 +01:00
|
|
|
}
|
|
|
|
|
2018-05-30 15:03:44 +01:00
|
|
|
const (
|
2018-05-16 19:47:59 +01:00
|
|
|
id ID = "SrvID"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Main initializes a new Service
|
2018-05-30 15:03:44 +01:00
|
|
|
func Main(s Service) (err error) {
|
|
|
|
flagfile.Load()
|
|
|
|
|
2018-05-16 19:47:59 +01:00
|
|
|
ctx := context.Background()
|
|
|
|
|
2018-05-30 15:03:44 +01:00
|
|
|
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)))
|
2018-05-16 19:47:59 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer logger.Sync()
|
2018-05-30 15:03:44 +01:00
|
|
|
defer zap.ReplaceGlobals(logger)()
|
|
|
|
defer zap.RedirectStdLog(logger)()
|
2018-05-16 19:47:59 +01:00
|
|
|
|
|
|
|
s.SetLogger(logger)
|
2018-05-30 15:03:44 +01:00
|
|
|
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))
|
|
|
|
}
|
2018-05-16 19:47:59 +01:00
|
|
|
|
|
|
|
return s.Process(ctx)
|
|
|
|
}
|
2018-05-30 15:03:44 +01:00
|
|
|
|
|
|
|
// Must can be used for default Main error handling
|
|
|
|
func Must(err error) {
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|