Compare commits

..

3 Commits

Author SHA1 Message Date
Yavolte 2812e46444 adjuest logger interface 2025-07-04 14:26:07 +08:00
Yavolte fb585fabe6 use jwt claims 2025-06-30 11:25:55 +08:00
Yavolte 29d609ce0a fix cache bugs 2025-06-30 11:11:34 +08:00
10 changed files with 125 additions and 25 deletions

15
app.go
View File

@ -109,10 +109,14 @@ func (s *Service) injectVars(v any) {
continue continue
} }
fieldType := refType.Field(i) fieldType := refType.Field(i)
if fieldType.Type.Kind() != reflect.Ptr { if !(fieldType.Type.Kind() != reflect.Ptr || fieldType.Type.Kind() != reflect.Interface) {
continue continue
} }
for _, rv := range s.refValues { for _, rv := range s.refValues {
if fieldType.Type.Kind() == reflect.Interface && rv.Type().Implements(fieldType.Type) {
refValue.Field(i).Set(rv)
break
}
if fieldType.Type == rv.Type() { if fieldType.Type == rv.Type() {
refValue.Field(i).Set(rv) refValue.Field(i).Set(rv)
break break
@ -123,7 +127,10 @@ func (s *Service) injectVars(v any) {
func (s *Service) preStart(ctx context.Context) (err error) { func (s *Service) preStart(ctx context.Context) (err error) {
s.Logger().Info(ctx, "starting") s.Logger().Info(ctx, "starting")
s.refValues = append(s.refValues, s.opts.injectVars...)
s.refValues = append(s.refValues, reflect.ValueOf(s.Logger()))
for _, ptr := range s.opts.servers { for _, ptr := range s.opts.servers {
s.injectVars(ptr)
s.refValues = append(s.refValues, reflect.ValueOf(ptr)) s.refValues = append(s.refValues, reflect.ValueOf(ptr))
} }
if s.opts.registry != nil { if s.opts.registry != nil {
@ -185,7 +192,7 @@ func (s *Service) preStart(ctx context.Context) (err error) {
o.Context = ctx o.Context = ctx
o.TTL = s.opts.registrarTimeout o.TTL = s.opts.registrarTimeout
}); err != nil { }); err != nil {
s.Logger().Warn(ctx, "service register error: %v", err) s.Logger().Warnf(ctx, "service register error: %v", err)
} }
} }
} }
@ -206,14 +213,14 @@ func (s *Service) preStop() (err error) {
}() }()
for _, srv := range s.opts.servers { for _, srv := range s.opts.servers {
if err = srv.Stop(ctx); err != nil { if err = srv.Stop(ctx); err != nil {
s.Logger().Warn(ctx, "server stop error: %v", err) s.Logger().Warnf(ctx, "server stop error: %v", err)
} }
} }
if s.opts.registry != nil { if s.opts.registry != nil {
if err = s.opts.registry.Deregister(s.service, func(o *registry.DeregisterOptions) { if err = s.opts.registry.Deregister(s.service, func(o *registry.DeregisterOptions) {
o.Context = ctx o.Context = ctx
}); err != nil { }); err != nil {
s.Logger().Warn(ctx, "server deregister error: %v", err) s.Logger().Warnf(ctx, "server deregister error: %v", err)
} }
} }
s.Logger().Info(ctx, "stopped") s.Logger().Info(ctx, "stopped")

View File

@ -57,9 +57,16 @@ func WithAllow(paths ...string) Option {
} }
} }
func WithClaims(claims reflect.Type) Option { func WithClaims(claims any) Option {
return func(o *options) { return func(o *options) {
o.claims = claims if tv, ok := claims.(reflect.Type); ok {
o.claims = tv
} else {
o.claims = reflect.TypeOf(claims)
if o.claims.Kind() == reflect.Ptr {
o.claims = o.claims.Elem()
}
}
} }
} }

View File

@ -3,6 +3,7 @@ package aeus
import ( import (
"context" "context"
"maps" "maps"
"reflect"
"time" "time"
"git.nobla.cn/golang/aeus/pkg/logger" "git.nobla.cn/golang/aeus/pkg/logger"
@ -24,6 +25,7 @@ type options struct {
registry registry.Registry registry registry.Registry
serviceLoader ServiceLoader serviceLoader ServiceLoader
stopTimeout time.Duration stopTimeout time.Duration
injectVars []reflect.Value
} }
func WithName(name string) Option { func WithName(name string) Option {
@ -77,6 +79,14 @@ func WithDebug(debug bool) Option {
} }
} }
func WithInjectVars(vars ...any) Option {
return func(o *options) {
for _, v := range vars {
o.injectVars = append(o.injectVars, reflect.ValueOf(v))
}
}
}
func WithServiceLoader(loader ServiceLoader) Option { func WithServiceLoader(loader ServiceLoader) Option {
return func(o *options) { return func(o *options) {
o.serviceLoader = loader o.serviceLoader = loader

View File

@ -4,6 +4,8 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"time" "time"
"git.nobla.cn/golang/aeus"
) )
type redisCache struct { type redisCache struct {
@ -57,7 +59,12 @@ func (c *redisCache) String() string {
} }
func NewCache(opts ...Option) *redisCache { func NewCache(opts ...Option) *redisCache {
return &redisCache{ cache := &redisCache{
opts: newOptions(opts...), opts: newOptions(opts...),
} }
app := aeus.FromContext(cache.opts.context)
if app != nil {
cache.opts.prefix = app.Name() + ":" + cache.opts.prefix
}
return cache
} }

View File

@ -1,13 +1,16 @@
package redis package redis
import ( import (
"context"
"github.com/redis/go-redis/v9" "github.com/redis/go-redis/v9"
) )
type ( type (
options struct { options struct {
client *redis.Client context context.Context
prefix string client *redis.Client
prefix string
} }
Option func(*options) Option func(*options)
@ -19,6 +22,12 @@ func WithClient(client *redis.Client) Option {
} }
} }
func WithContext(ctx context.Context) Option {
return func(o *options) {
o.context = ctx
}
}
func WithPrefix(prefix string) Option { func WithPrefix(prefix string) Option {
return func(o *options) { return func(o *options) {
o.prefix = prefix o.prefix = prefix

View File

@ -3,6 +3,7 @@ package logger
import ( import (
"context" "context"
"log/slog" "log/slog"
"os"
) )
var ( var (
@ -10,32 +11,56 @@ var (
) )
func init() { func init() {
log = NewLogger(slog.Default()) log = NewLogger(slog.New(
slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{
Level: slog.LevelDebug,
}),
))
} }
type Logger interface { type Logger interface {
Debug(ctx context.Context, format string, args ...any) Debug(ctx context.Context, format string, args ...any) //Structured context as loosely typed key-value pairs.
Debugf(ctx context.Context, format string, args ...any)
Info(ctx context.Context, format string, args ...any) Info(ctx context.Context, format string, args ...any)
Infof(ctx context.Context, format string, args ...any)
Warn(ctx context.Context, format string, args ...any) Warn(ctx context.Context, format string, args ...any)
Warnf(ctx context.Context, format string, args ...any)
Error(ctx context.Context, format string, args ...any) Error(ctx context.Context, format string, args ...any)
Errorf(ctx context.Context, format string, args ...any)
} }
func Debug(ctx context.Context, format string, args ...any) { func Debug(ctx context.Context, format string, args ...any) {
log.Debug(ctx, format, args...) log.Debug(ctx, format, args...)
} }
func Debugf(ctx context.Context, format string, args ...any) {
log.Debugf(ctx, format, args...)
}
func Info(ctx context.Context, format string, args ...any) { func Info(ctx context.Context, format string, args ...any) {
log.Debug(ctx, format, args...) log.Info(ctx, format, args...)
}
func Infof(ctx context.Context, format string, args ...any) {
log.Infof(ctx, format, args...)
} }
func Warn(ctx context.Context, format string, args ...any) { func Warn(ctx context.Context, format string, args ...any) {
log.Debug(ctx, format, args...) log.Warn(ctx, format, args...)
}
func Warnf(ctx context.Context, format string, args ...any) {
log.Warnf(ctx, format, args...)
} }
func Error(ctx context.Context, format string, args ...any) { func Error(ctx context.Context, format string, args ...any) {
log.Debug(ctx, format, args...) log.Debug(ctx, format, args...)
} }
func Errorf(ctx context.Context, format string, args ...any) {
log.Errorf(ctx, format, args...)
}
func Default() Logger { func Default() Logger {
return log return log
} }

View File

@ -11,18 +11,34 @@ type logger struct {
} }
func (l *logger) Debug(ctx context.Context, msg string, args ...any) { func (l *logger) Debug(ctx context.Context, msg string, args ...any) {
l.log.DebugContext(ctx, msg, args...)
}
func (l *logger) Debugf(ctx context.Context, msg string, args ...any) {
l.log.DebugContext(ctx, fmt.Sprintf(msg, args...)) l.log.DebugContext(ctx, fmt.Sprintf(msg, args...))
} }
func (l *logger) Info(ctx context.Context, msg string, args ...any) { func (l *logger) Info(ctx context.Context, msg string, args ...any) {
l.log.InfoContext(ctx, msg, args...)
}
func (l *logger) Infof(ctx context.Context, msg string, args ...any) {
l.log.InfoContext(ctx, fmt.Sprintf(msg, args...)) l.log.InfoContext(ctx, fmt.Sprintf(msg, args...))
} }
func (l *logger) Warn(ctx context.Context, msg string, args ...any) { func (l *logger) Warn(ctx context.Context, msg string, args ...any) {
l.log.WarnContext(ctx, msg, args...)
}
func (l *logger) Warnf(ctx context.Context, msg string, args ...any) {
l.log.WarnContext(ctx, fmt.Sprintf(msg, args...)) l.log.WarnContext(ctx, fmt.Sprintf(msg, args...))
} }
func (l *logger) Error(ctx context.Context, msg string, args ...any) { func (l *logger) Error(ctx context.Context, msg string, args ...any) {
l.log.ErrorContext(ctx, msg, args...)
}
func (l *logger) Errorf(ctx context.Context, msg string, args ...any) {
l.log.ErrorContext(ctx, fmt.Sprintf(msg, args...)) l.log.ErrorContext(ctx, fmt.Sprintf(msg, args...))
} }

View File

@ -32,6 +32,7 @@ type Server struct {
uri *url.URL uri *url.URL
exitFlag int32 exitFlag int32
middleware []middleware.Middleware middleware []middleware.Middleware
Logger logger.Logger
} }
func (svr *Server) Use(middlewares ...middleware.Middleware) { func (svr *Server) Use(middlewares ...middleware.Middleware) {
@ -134,7 +135,7 @@ func (s *Server) execute(ctx *Context, frame *Frame) (err error) {
func (svr *Server) nextSequence() int64 { func (svr *Server) nextSequence() int64 {
svr.sequenceLocker.Lock() svr.sequenceLocker.Lock()
defer svr.sequenceLocker.Unlock() defer svr.sequenceLocker.Unlock()
if svr.sequence >= math.MaxInt64 { if svr.sequence == math.MaxInt64 {
svr.sequence = 1 svr.sequence = 1
} }
svr.sequence++ svr.sequence++
@ -208,10 +209,16 @@ func (s *Server) serve() (err error) {
func (s *Server) Start(ctx context.Context) (err error) { func (s *Server) Start(ctx context.Context) (err error) {
s.ctx = ctx s.ctx = ctx
if s.opts.logger != nil {
s.Logger = s.opts.logger
}
if s.Logger == nil {
s.Logger = logger.Default()
}
if err = s.createListener(); err != nil { if err = s.createListener(); err != nil {
return return
} }
s.opts.logger.Info(ctx, "cli server listen on: %s", s.uri.Host) s.Logger.Infof(ctx, "cli server listen on: %s", s.uri.Host)
s.Handle("/help", "Display help information", func(ctx *Context) (err error) { s.Handle("/help", "Display help information", func(ctx *Context) (err error) {
return ctx.Success(s.router.String()) return ctx.Success(s.router.String())
}) })
@ -224,7 +231,9 @@ func (s *Server) Stop(ctx context.Context) (err error) {
return return
} }
if s.listener != nil { if s.listener != nil {
err = s.listener.Close() if err = s.listener.Close(); err != nil {
s.Logger.Warnf(ctx, "cli listener close error: %v", err)
}
} }
s.ctxMap.Range(func(key, value any) bool { s.ctxMap.Range(func(key, value any) bool {
if ctx, ok := value.(*Context); ok { if ctx, ok := value.(*Context); ok {
@ -232,6 +241,7 @@ func (s *Server) Stop(ctx context.Context) (err error) {
} }
return true return true
}) })
s.Logger.Info(ctx, "cli server stopped")
return return
} }
@ -240,7 +250,6 @@ func New(cbs ...Option) *Server {
opts: &options{ opts: &options{
network: "tcp", network: "tcp",
address: ":0", address: ":0",
logger: logger.Default(),
}, },
uri: &url.URL{Scheme: "cli"}, uri: &url.URL{Scheme: "cli"},
router: newRouter(""), router: newRouter(""),

View File

@ -25,6 +25,7 @@ type Server struct {
serve *grpc.Server serve *grpc.Server
listener net.Listener listener net.Listener
middlewares []middleware.Middleware middlewares []middleware.Middleware
Logger logger.Logger
} }
func (s *Server) createListener() (err error) { func (s *Server) createListener() (err error) {
@ -107,11 +108,16 @@ func (s *Server) Use(middlewares ...middleware.Middleware) {
func (s *Server) Start(ctx context.Context) (err error) { func (s *Server) Start(ctx context.Context) (err error) {
s.ctx = ctx s.ctx = ctx
if s.opts.logger != nil {
s.Logger = s.opts.logger
}
if s.Logger == nil {
s.Logger = logger.Default()
}
if err = s.createListener(); err != nil { if err = s.createListener(); err != nil {
return return
} }
s.opts.logger.Info(ctx, "grpc server listen on: %s", s.uri.Host) s.Logger.Infof(ctx, "grpc server listen on: %s", s.uri.Host)
reflection.Register(s.serve) reflection.Register(s.serve)
s.serve.Serve(s.listener) s.serve.Serve(s.listener)
return return
@ -130,7 +136,7 @@ func (s *Server) RegisterService(sd *grpc.ServiceDesc, ss any) {
func (s *Server) Stop(ctx context.Context) (err error) { func (s *Server) Stop(ctx context.Context) (err error) {
s.serve.GracefulStop() s.serve.GracefulStop()
s.opts.logger.Info(s.ctx, "grpc server stopped") s.Logger.Infof(s.ctx, "grpc server stopped")
return return
} }
@ -138,7 +144,6 @@ func New(cbs ...Option) *Server {
svr := &Server{ svr := &Server{
opts: &options{ opts: &options{
network: "tcp", network: "tcp",
logger: logger.Default(),
grpcOpts: make([]grpc.ServerOption, 0, 10), grpcOpts: make([]grpc.ServerOption, 0, 10),
}, },
uri: &url.URL{ uri: &url.URL{

View File

@ -36,6 +36,7 @@ type Server struct {
listener net.Listener listener net.Listener
fs *filesystem fs *filesystem
middlewares []middleware.Middleware middlewares []middleware.Middleware
Logger logger.Logger
} }
func (s *Server) Endpoint(ctx context.Context) (string, error) { func (s *Server) Endpoint(ctx context.Context) (string, error) {
@ -156,7 +157,6 @@ func (s *Server) staticHandle(ctx *gin.Context, fp http.File) {
} }
http.ServeContent(ctx.Writer, ctx.Request, path.Base(uri), s.fs.modtime, fp) http.ServeContent(ctx.Writer, ctx.Request, path.Base(uri), s.fs.modtime, fp)
ctx.Abort() ctx.Abort()
return
} }
func (s *Server) notFoundHandle(ctx *gin.Context) { func (s *Server) notFoundHandle(ctx *gin.Context) {
@ -255,6 +255,12 @@ func (s *Server) Start(ctx context.Context) (err error) {
Addr: s.opts.address, Addr: s.opts.address,
Handler: s.engine, Handler: s.engine,
} }
if s.opts.logger != nil {
s.Logger = s.opts.logger
}
if s.Logger == nil {
s.Logger = logger.Default()
}
s.ctx = ctx s.ctx = ctx
if s.opts.debug { if s.opts.debug {
s.engine.Handle(http.MethodGet, "/debug/pprof/", s.wrapHandle(pprof.Index)) s.engine.Handle(http.MethodGet, "/debug/pprof/", s.wrapHandle(pprof.Index))
@ -271,7 +277,7 @@ func (s *Server) Start(ctx context.Context) (err error) {
return return
} }
s.engine.NoRoute(s.notFoundHandle) s.engine.NoRoute(s.notFoundHandle)
s.opts.logger.Info(ctx, "http server listen on: %s", s.uri.Host) s.Logger.Infof(ctx, "http server listen on: %s", s.uri.Host)
if s.opts.certFile != "" && s.opts.keyFile != "" { if s.opts.certFile != "" && s.opts.keyFile != "" {
s.uri.Scheme = "https" s.uri.Scheme = "https"
err = s.serve.ServeTLS(s.listener, s.opts.certFile, s.opts.keyFile) err = s.serve.ServeTLS(s.listener, s.opts.certFile, s.opts.keyFile)
@ -286,7 +292,7 @@ func (s *Server) Start(ctx context.Context) (err error) {
func (s *Server) Stop(ctx context.Context) (err error) { func (s *Server) Stop(ctx context.Context) (err error) {
err = s.serve.Shutdown(ctx) err = s.serve.Shutdown(ctx)
s.opts.logger.Info(ctx, "http server stopped") s.Logger.Infof(ctx, "http server stopped")
return return
} }
@ -295,7 +301,6 @@ func New(cbs ...Option) *Server {
uri: &url.URL{Scheme: "http"}, uri: &url.URL{Scheme: "http"},
opts: &options{ opts: &options{
network: "tcp", network: "tcp",
logger: logger.Default(),
}, },
} }
port, _ := strconv.Atoi(os.Getenv("HTTP_PORT")) port, _ := strconv.Atoi(os.Getenv("HTTP_PORT"))