@ -3,12 +3,16 @@ package recovery
import (
import (
"context"
"context"
"runtime"
"runtime"
"time"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/log"
"github.com/go-kratos/kratos/v2/middleware"
"github.com/go-kratos/kratos/v2/middleware"
)
)
// Latency is recovery latency context key
type Latency struct { }
// ErrUnknownRequest is unknown request error.
// ErrUnknownRequest is unknown request error.
var ErrUnknownRequest = errors . InternalServer ( "UNKNOWN" , "unknown request error" )
var ErrUnknownRequest = errors . InternalServer ( "UNKNOWN" , "unknown request error" )
@ -41,13 +45,14 @@ func Recovery(opts ...Option) middleware.Middleware {
}
}
return func ( handler middleware . Handler ) middleware . Handler {
return func ( handler middleware . Handler ) middleware . Handler {
return func ( ctx context . Context , req interface { } ) ( reply interface { } , err error ) {
return func ( ctx context . Context , req interface { } ) ( reply interface { } , err error ) {
startTime := time . Now ( )
defer func ( ) {
defer func ( ) {
if rerr := recover ( ) ; rerr != nil {
if rerr := recover ( ) ; rerr != nil {
buf := make ( [ ] byte , 64 << 10 ) //nolint:gomnd
buf := make ( [ ] byte , 64 << 10 ) //nolint:gomnd
n := runtime . Stack ( buf , false )
n := runtime . Stack ( buf , false )
buf = buf [ : n ]
buf = buf [ : n ]
log . Context ( ctx ) . Errorf ( "%v: %+v\n%s\n" , rerr , req , buf )
log . Context ( ctx ) . Errorf ( "%v: %+v\n%s\n" , rerr , req , buf )
ctx = context . WithValue ( ctx , Latency { } , time . Since ( startTime ) . Seconds ( ) )
err = op . handler ( ctx , req , rerr )
err = op . handler ( ctx , req , rerr )
}
}
} ( )
} ( )