func (g *Group) RunConfig() (interrupted bool, err error) {
	g.log = logger.GetLogger(g.Name)
	g.configured = true
	if g.Name == "" {
		g.Name = path.Base(os.Args[0])
	}
	defer func() {
		if err != nil {
			g.log.Error().Err(err).Msg("unexpected exit")
		}
	}()
	if err = config.Load(g.f.Name, g.f.FlagSet); err != nil {
		return false, err
	}
	switch {
	case g.showRunGroup:
		fmt.Println(g.ListUnits())
		return true, nil
	}
	for idx := range g.c {
		if g.c[idx] == nil {
			g.log.Debug().Uint32("ran", uint32(idx+1)).Msg("skipping validate")
			continue
		}
		g.log.Debug().Str("name", g.c[idx].Name()).Uint32("ran", uint32(idx+1)).Uint32("total", uint32(len(g.c))).Msg("validate config")
		if vErr := g.c[idx].Validate(); vErr != nil {
			err = multierr.Append(err, vErr)
		}
	}
	if err != nil {
		return false, err
	}
	g.log.Info().Msg("started")
	return false, nil
}
RunConfig runs the Config phase of all registered Config aware Units.
Only use this function if needing to add additional wiring between config
and (pre)run phases and a separate PreRunner phase is not an option.
In most cases it is best to use the Run method directly as it will run the
Config phase prior to executing the PreRunner and Service phases.
If an error is returned the application must shut down as it is considered
fatal.
package run
import (
	"fmt"
	"os"
	"path"
	"github.com/oklog/run"
	"github.com/spf13/pflag"
	"go.uber.org/multierr"
	"github.com/apache/skywalking-banyandb/pkg/config"
	"github.com/apache/skywalking-banyandb/pkg/logger"
)
type FlagSet struct {
	*pflag.FlagSet
	Name string
}
func NewFlagSet(name string) *FlagSet {
	return &FlagSet{
		FlagSet: pflag.NewFlagSet(name, pflag.ContinueOnError),
		Name:    name,
	}
}
type Unit interface {
	Name() string
}
type Config interface {
	Unit
	FlagSet() *FlagSet
	Validate() error
}
type PreRunner interface {
	Unit
	PreRun() error
}
func NewPreRunner(name string, fn func() error) PreRunner {
	return preRunner{name: name, fn: fn}
}
type preRunner struct {
	name string
	fn   func() error
}
func (p preRunner) Name() string {
	return p.name
}
func (p preRunner) PreRun() error {
	return p.fn()
}
type Service interface {
	Unit
	Serve() error
	GracefulStop()
}
type Group struct {
	Name string
	f   *FlagSet
	r   run.Group
	c   []Config
	p   []PreRunner
	s   []Service
	log *logger.Logger
	showRunGroup bool
	configured bool
}
func (g *Group) Register(units ...Unit) []bool {
	g.log = logger.GetLogger(g.Name)
	hasRegistered := make([]bool, len(units))
	for idx := range units {
		if !g.configured {
			if c, ok := units[idx].(Config); ok {
				g.c = append(g.c, c)
				hasRegistered[idx] = true
			}
		}
		if p, ok := units[idx].(PreRunner); ok {
			g.p = append(g.p, p)
			hasRegistered[idx] = true
		}
		if s, ok := units[idx].(Service); ok {
			g.s = append(g.s, s)
			hasRegistered[idx] = true
		}
	}
	return hasRegistered
}
func (g *Group) RegisterFlags() *FlagSet {
	g.f = NewFlagSet(g.Name)
	g.f.SortFlags = false  
	g.f.Usage = func() {
		fmt.Printf("Flags:\n")
		g.f.PrintDefaults()
	}
	gFS := NewFlagSet("Common Service options")
	gFS.SortFlags = false
	gFS.StringVarP(&g.Name, "name", "n", g.Name, `name of this service`)
	gFS.BoolVar(&g.showRunGroup, "show-rungroup-units", false, "show rungroup units")
	g.f.AddFlagSet(gFS.FlagSet)
	fs := make([]*FlagSet, len(g.c))
	for idx := range g.c {
		if g.c[idx] == nil {
			continue
		}
		g.log.Debug().Str("name", g.c[idx].Name()).Uint32("registered", uint32(idx+1)).Uint32("total", uint32(len(g.c))).Msg("register flags")
		fs[idx] = g.c[idx].FlagSet()
		if fs[idx] == nil {
			g.log.Debug().Str("name", g.c[idx].Name()).Msg("config object did not return a flagset")
			continue
		}
		fs[idx].VisitAll(func(f *pflag.Flag) {
			if g.f.Lookup(f.Name) != nil {
				g.log.Warn().Str("name", f.Name).Uint32("registered", uint32(idx+1)).Msg("ignoring duplicate flag")
				return
			}
			g.f.AddFlag(f)
		})
	}
	return g.f
}