Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
931ddb7c
Unverified
Commit
931ddb7c
authored
Aug 07, 2025
by
Brandon Sprague
Committed by
GitHub
Aug 07, 2025
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: add a new LOG_STACKTRACES option (#4973)
parent
8576001c
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
54 additions
and
5 deletions
+54
-5
logger_interceptor.go
server/router/api/v1/logger_interceptor.go
+8
-3
server.go
server/server.go
+46
-2
No files found.
server/router/api/v1/logger_interceptor.go
View file @
931ddb7c
...
@@ -2,6 +2,7 @@ package v1
...
@@ -2,6 +2,7 @@ package v1
import
(
import
(
"context"
"context"
"fmt"
"log/slog"
"log/slog"
"google.golang.org/grpc"
"google.golang.org/grpc"
...
@@ -10,10 +11,11 @@ import (
...
@@ -10,10 +11,11 @@ import (
)
)
type
LoggerInterceptor
struct
{
type
LoggerInterceptor
struct
{
logStacktrace
bool
}
}
func
NewLoggerInterceptor
()
*
LoggerInterceptor
{
func
NewLoggerInterceptor
(
logStacktrace
bool
)
*
LoggerInterceptor
{
return
&
LoggerInterceptor
{}
return
&
LoggerInterceptor
{
logStacktrace
:
logStacktrace
}
}
}
func
(
in
*
LoggerInterceptor
)
LoggerInterceptor
(
ctx
context
.
Context
,
request
any
,
serverInfo
*
grpc
.
UnaryServerInfo
,
handler
grpc
.
UnaryHandler
)
(
any
,
error
)
{
func
(
in
*
LoggerInterceptor
)
LoggerInterceptor
(
ctx
context
.
Context
,
request
any
,
serverInfo
*
grpc
.
UnaryServerInfo
,
handler
grpc
.
UnaryHandler
)
(
any
,
error
)
{
...
@@ -22,7 +24,7 @@ func (in *LoggerInterceptor) LoggerInterceptor(ctx context.Context, request any,
...
@@ -22,7 +24,7 @@ func (in *LoggerInterceptor) LoggerInterceptor(ctx context.Context, request any,
return
resp
,
err
return
resp
,
err
}
}
func
(
*
LoggerInterceptor
)
loggerInterceptorDo
(
ctx
context
.
Context
,
fullMethod
string
,
err
error
)
{
func
(
in
*
LoggerInterceptor
)
loggerInterceptorDo
(
ctx
context
.
Context
,
fullMethod
string
,
err
error
)
{
st
:=
status
.
Convert
(
err
)
st
:=
status
.
Convert
(
err
)
var
logLevel
slog
.
Level
var
logLevel
slog
.
Level
var
logMsg
string
var
logMsg
string
...
@@ -43,6 +45,9 @@ func (*LoggerInterceptor) loggerInterceptorDo(ctx context.Context, fullMethod st
...
@@ -43,6 +45,9 @@ func (*LoggerInterceptor) loggerInterceptorDo(ctx context.Context, fullMethod st
logAttrs
:=
[]
slog
.
Attr
{
slog
.
String
(
"method"
,
fullMethod
)}
logAttrs
:=
[]
slog
.
Attr
{
slog
.
String
(
"method"
,
fullMethod
)}
if
err
!=
nil
{
if
err
!=
nil
{
logAttrs
=
append
(
logAttrs
,
slog
.
String
(
"error"
,
err
.
Error
()))
logAttrs
=
append
(
logAttrs
,
slog
.
String
(
"error"
,
err
.
Error
()))
if
in
.
logStacktrace
{
logAttrs
=
append
(
logAttrs
,
slog
.
String
(
"stacktrace"
,
fmt
.
Sprintf
(
"%v"
,
err
)))
}
}
}
slog
.
LogAttrs
(
ctx
,
logLevel
,
logMsg
,
logAttrs
...
)
slog
.
LogAttrs
(
ctx
,
logLevel
,
logMsg
,
logAttrs
...
)
}
}
server/server.go
View file @
931ddb7c
...
@@ -8,6 +8,7 @@ import (
...
@@ -8,6 +8,7 @@ import (
"net"
"net"
"net/http"
"net/http"
"runtime"
"runtime"
"runtime/debug"
"time"
"time"
"github.com/google/uuid"
"github.com/google/uuid"
...
@@ -83,12 +84,15 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
...
@@ -83,12 +84,15 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
// Create and register RSS routes.
// Create and register RSS routes.
rss
.
NewRSSService
(
s
.
Profile
,
s
.
Store
)
.
RegisterRoutes
(
rootGroup
)
rss
.
NewRSSService
(
s
.
Profile
,
s
.
Store
)
.
RegisterRoutes
(
rootGroup
)
// Log full stacktraces if we're in dev
logStacktraces
:=
profile
.
IsDev
()
grpcServer
:=
grpc
.
NewServer
(
grpcServer
:=
grpc
.
NewServer
(
// Override the maximum receiving message size to math.MaxInt32 for uploading large attachments.
// Override the maximum receiving message size to math.MaxInt32 for uploading large attachments.
grpc
.
MaxRecvMsgSize
(
math
.
MaxInt32
),
grpc
.
MaxRecvMsgSize
(
math
.
MaxInt32
),
grpc
.
ChainUnaryInterceptor
(
grpc
.
ChainUnaryInterceptor
(
apiv1
.
NewLoggerInterceptor
()
.
LoggerInterceptor
,
apiv1
.
NewLoggerInterceptor
(
logStacktraces
)
.
LoggerInterceptor
,
grpcrecovery
.
UnaryServerInterceptor
(
),
newRecoveryInterceptor
(
logStacktraces
),
apiv1
.
NewGRPCAuthInterceptor
(
store
,
secret
)
.
AuthenticationInterceptor
,
apiv1
.
NewGRPCAuthInterceptor
(
store
,
secret
)
.
AuthenticationInterceptor
,
))
))
s
.
grpcServer
=
grpcServer
s
.
grpcServer
=
grpcServer
...
@@ -102,6 +106,26 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
...
@@ -102,6 +106,26 @@ func NewServer(ctx context.Context, profile *profile.Profile, store *store.Store
return
s
,
nil
return
s
,
nil
}
}
func
newRecoveryInterceptor
(
logStacktraces
bool
)
grpc
.
UnaryServerInterceptor
{
var
recoveryOptions
[]
grpcrecovery
.
Option
if
logStacktraces
{
recoveryOptions
=
append
(
recoveryOptions
,
grpcrecovery
.
WithRecoveryHandler
(
func
(
p
any
)
error
{
if
p
==
nil
{
return
nil
}
switch
val
:=
p
.
(
type
)
{
case
runtime
.
Error
:
return
&
stacktraceError
{
err
:
val
,
stacktrace
:
debug
.
Stack
()}
default
:
return
nil
}
}))
}
return
grpcrecovery
.
UnaryServerInterceptor
(
recoveryOptions
...
)
}
func
(
s
*
Server
)
Start
(
ctx
context
.
Context
)
error
{
func
(
s
*
Server
)
Start
(
ctx
context
.
Context
)
error
{
var
address
,
network
string
var
address
,
network
string
if
len
(
s
.
Profile
.
UNIXSock
)
==
0
{
if
len
(
s
.
Profile
.
UNIXSock
)
==
0
{
...
@@ -227,3 +251,23 @@ func (s *Server) getOrUpsertWorkspaceBasicSetting(ctx context.Context) (*storepb
...
@@ -227,3 +251,23 @@ func (s *Server) getOrUpsertWorkspaceBasicSetting(ctx context.Context) (*storepb
}
}
return
workspaceBasicSetting
,
nil
return
workspaceBasicSetting
,
nil
}
}
// stacktraceError wraps an underlying error and captures the stacktrace. It
// implements fmt.Formatter, so it'll be rendered when invoked by something like
// `fmt.Sprint("%v", err)`.
type
stacktraceError
struct
{
err
error
stacktrace
[]
byte
}
func
(
e
*
stacktraceError
)
Error
()
string
{
return
e
.
err
.
Error
()
}
func
(
e
*
stacktraceError
)
Unwrap
()
error
{
return
e
.
err
}
func
(
e
*
stacktraceError
)
Format
(
f
fmt
.
State
,
_
rune
)
{
f
.
Write
(
e
.
stacktrace
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment