package app import ( "context" "errors" "github.com/skeris/appInit" "github.com/themakers/hlog" "go.uber.org/zap" "go.uber.org/zap/zapcore" "google.golang.org/grpc" "net" "penahub.gitlab.yandexcloud.net/external/trashlog.git/dal/clickhouse" trashlogProto "penahub.gitlab.yandexcloud.net/external/trashlog.git/proto/generated" "penahub.gitlab.yandexcloud.net/external/trashlog.git/sink" "penahub.gitlab.yandexcloud.net/external/trashlog.git/version" "penahub.gitlab.yandexcloud.net/external/trashlog.git/wrappers/zaptg" ) type App struct { err chan error logger *zap.Logger } var ( errInvalidOptions = errors.New("invalid options") ) type Options struct { Development bool `env:"DEVELOPMENT" default:"true"` AppName string `env:"APP_NAME" default:"trashlog"` Addr string `env:"APP_ADDR" default:":7113"` ClickhouseCred string `env:"CH_CRED" default:"tcp://127.0.0.1:9000?debug=true"` } var _ appInit.CommonApp = (*App)(nil) type InfoSvcStarted struct{} type InfoSvcReady struct{} type InfoSvcShutdown struct { Signal string } type ErrorCanNotServe struct { Err error } type ErrorFailToConnectTarantool struct { Err error } type ErrorListener struct { Err error } type ErrorServe struct { Err error } type ErrorStoreInit struct { Err error } type ErrorStoreConnect struct { Err error Credentials string } var zapOptions = []zap.Option{ zap.AddCaller(), zap.AddCallerSkip(2), zap.AddStacktrace(zap.ErrorLevel), } func New(ctx context.Context, opts interface{}, ver appInit.Version) (appInit.CommonApp, error) { var ( err error errChan = make(chan error) logger *zap.Logger options Options ok bool ) if options, ok = opts.(Options); !ok { return App{}, errInvalidOptions } if options.Development { logger, err = zap.NewDevelopment(zapOptions...) } else { logger, err = zap.NewProduction(zapOptions...) } if err != nil { return nil, err } logger = logger.Named(options.AppName) logger = logger.With( zap.String("SvcCommit", version.Commit), zap.String("SvcVersion", version.Release), zap.String("SvcBuildTime", version.BuildTime), ) tel, err := zaptg.NewCore( ctx, zap.InfoLevel, "1408111289:AAHfWZRiBQRncb2gl2LtU8OeASjfJi4e8YE", version.Release, version.Commit, 0, -1001256687920, ) if err != nil { panic(err) } logger = logger.WithOptions(zap.WrapCore(func(core zapcore.Core) zapcore.Core { return zapcore.NewTee(core, tel) })) log := hlog.New(logger) log.Emit(InfoSvcStarted{}) log.Emit(InfoSvcReady{}) listener, err := net.Listen("tcp", options.Addr) if err != nil { log.Emit(ErrorListener{Err: err}) return nil, err } logStore, err := clickhouse.New(ctx, log, options.ClickhouseCred) if err != nil { log.Emit(ErrorStoreConnect{ Err: err, Credentials: options.ClickhouseCred, }) return nil, err } if err := logStore.Init(ctx); err != nil { log.Emit(ErrorStoreInit{ Err: err, }) return nil, err } log.With(map[string]string{ "test": "test2", "test1": "test3", }) sinkSvc := sink.New(log, logStore) var grpcOpts []grpc.ServerOption grpcServer := grpc.NewServer(grpcOpts...) trashlogProto.RegisterTrashlogServer(grpcServer, sinkSvc) go func() { if err := grpcServer.Serve(listener); err != nil { log.Emit(ErrorServe{ Err: err, }) errChan <- err } }() return App{ err: errChan, logger: logger, }, nil } func (a App) GetLogger() *zap.Logger { return a.logger } func (a App) GetErr() chan error { return a.err }