Skip to content

Commit 42d4014

Browse files
committed
proxy: stats will record error response (including rewritten internel errors)
1 parent 365c911 commit 42d4014

File tree

5 files changed

+70
-31
lines changed

5 files changed

+70
-31
lines changed

cmd/fe/assets/dashboard-fe.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,11 @@ function processProxyStats(codis_stats) {
246246
} else {
247247
if (s.stats.online) {
248248
p.sessions = "total=" + s.stats.sessions.total + ",alive=" + s.stats.sessions.alive;
249-
p.commands = "total=" + s.stats.ops.total + ",fails=" + s.stats.ops.fails + ",qps=" + s.stats.ops.qps;
249+
p.commands = "total=" + s.stats.ops.total + ",fails=" + s.stats.ops.fails;
250+
if (s.stats.ops.redis != undefined) {
251+
p.commands += ",errors=" + s.stats.ops.redis.errors;
252+
}
253+
p.commands += ",qps=" + s.stats.ops.qps;
250254
p.status = "HEALTHY";
251255
} else {
252256
p.status = "PENDING";

pkg/proxy/metrics.go

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ func (p *Proxy) startMetricsInfluxdb() {
9191
fields := map[string]interface{}{
9292
"ops_total": stats.Ops.Total,
9393
"ops_fails": stats.Ops.Fails,
94+
"ops_redis_errors": stats.Ops.Redis.Errors,
9495
"ops_qps": stats.Ops.QPS,
9596
"sessions_total": stats.Sessions.Total,
9697
"sessions_alive": stats.Sessions.Alive,

pkg/proxy/proxy.go

+8-4
Original file line numberDiff line numberDiff line change
@@ -461,10 +461,13 @@ type Stats struct {
461461
} `json:"sentinels"`
462462

463463
Ops struct {
464-
Total int64 `json:"total"`
465-
Fails int64 `json:"fails"`
466-
QPS int64 `json:"qps"`
467-
Cmd []*OpStats `json:"cmd,omitempty"`
464+
Total int64 `json:"total"`
465+
Fails int64 `json:"fails"`
466+
Redis struct {
467+
Errors int64 `json:"errors"`
468+
} `json:"redis"`
469+
QPS int64 `json:"qps"`
470+
Cmd []*OpStats `json:"cmd,omitempty"`
468471
} `json:"ops"`
469472

470473
Sessions struct {
@@ -553,6 +556,7 @@ func (s *Proxy) Stats(flags StatsFlags) *Stats {
553556

554557
stats.Ops.Total = OpTotal()
555558
stats.Ops.Fails = OpFails()
559+
stats.Ops.Redis.Errors = OpRedisErrors()
556560
stats.Ops.QPS = OpQPS()
557561

558562
if flags.HasBit(StatsCmds) {

pkg/proxy/session.go

+27-17
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,8 @@ func (s *Session) loopReader(tasks chan<- *Request, d *Router) (err error) {
179179
func (s *Session) loopWriter(tasks <-chan *Request) (err error) {
180180
defer func() {
181181
s.CloseWithError(err)
182-
for _ = range tasks {
183-
s.incrOpFails(nil)
182+
for r := range tasks {
183+
s.incrOpFails(r, nil)
184184
}
185185
s.flushOpStats(true)
186186
}()
@@ -197,16 +197,16 @@ func (s *Session) loopWriter(tasks <-chan *Request) (err error) {
197197
resp = redis.NewErrorf("ERR handle response, %s", err)
198198
if sensitive {
199199
s.Conn.Encode(resp, true)
200-
return s.incrOpFails(err)
200+
return s.incrOpFails(r, err)
201201
}
202202
}
203203
if err := p.Encode(resp); err != nil {
204-
return s.incrOpFails(err)
204+
return s.incrOpFails(r, err)
205205
}
206206
if err := p.Flush(len(tasks) == 0); err != nil {
207-
return s.incrOpFails(err)
207+
return s.incrOpFails(r, err)
208208
} else {
209-
s.incrOpStats(r)
209+
s.incrOpStats(r, resp.Type)
210210
}
211211
if len(tasks) == 0 {
212212
s.flushOpStats(false)
@@ -570,19 +570,29 @@ func (s *Session) incrOpTotal() {
570570
s.stats.total.Incr()
571571
}
572572

573-
func (s *Session) incrOpFails(err error) error {
574-
incrOpFails()
575-
return err
576-
}
577-
578-
func (s *Session) incrOpStats(r *Request) {
579-
e := s.stats.opmap[r.OpStr]
573+
func (s *Session) getOpStats(opstr string) *opStats {
574+
e := s.stats.opmap[opstr]
580575
if e == nil {
581-
e = &opStats{opstr: r.OpStr}
582-
s.stats.opmap[r.OpStr] = e
576+
e = &opStats{opstr: opstr}
577+
s.stats.opmap[opstr] = e
583578
}
579+
return e
580+
}
581+
582+
func (s *Session) incrOpStats(r *Request, t redis.RespType) {
583+
e := s.getOpStats(r.OpStr)
584584
e.calls.Incr()
585585
e.nsecs.Add(time.Now().UnixNano() - r.Start)
586+
switch t {
587+
case redis.TypeError:
588+
e.redis.errors.Incr()
589+
}
590+
}
591+
592+
func (s *Session) incrOpFails(r *Request, err error) error {
593+
e := s.getOpStats(r.OpStr)
594+
e.fails.Incr()
595+
return err
586596
}
587597

588598
func (s *Session) flushOpStats(force bool) {
@@ -597,8 +607,8 @@ func (s *Session) flushOpStats(force bool) {
597607

598608
incrOpTotal(s.stats.total.Swap(0))
599609
for _, e := range s.stats.opmap {
600-
if n := e.calls.Swap(0); n != 0 {
601-
incrOpStats(e.opstr, n, e.nsecs.Swap(0))
610+
if e.calls.Get() != 0 || e.fails.Get() != 0 {
611+
incrOpStats(e)
602612
}
603613
}
604614
s.stats.flush.n++

pkg/proxy/stats.go

+29-9
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,23 @@ type opStats struct {
1717
opstr string
1818
calls atomic2.Int64
1919
nsecs atomic2.Int64
20+
fails atomic2.Int64
21+
redis struct {
22+
errors atomic2.Int64
23+
}
2024
}
2125

2226
func (s *opStats) OpStats() *OpStats {
2327
o := &OpStats{
2428
OpStr: s.opstr,
2529
Calls: s.calls.Get(),
2630
Usecs: s.nsecs.Get() / 1e3,
31+
Fails: s.fails.Get(),
2732
}
2833
if o.Calls != 0 {
2934
o.UsecsPercall = o.Usecs / o.Calls
3035
}
36+
o.RedisErrType = s.redis.errors.Get()
3137
return o
3238
}
3339

@@ -36,14 +42,19 @@ type OpStats struct {
3642
Calls int64 `json:"calls"`
3743
Usecs int64 `json:"usecs"`
3844
UsecsPercall int64 `json:"usecs_percall"`
45+
Fails int64 `json:"fails"`
46+
RedisErrType int64 `json:"redis_errtype"`
3947
}
4048

4149
var cmdstats struct {
4250
sync.RWMutex
4351

52+
opmap map[string]*opStats
4453
total atomic2.Int64
4554
fails atomic2.Int64
46-
opmap map[string]*opStats
55+
redis struct {
56+
errors atomic2.Int64
57+
}
4758

4859
qps atomic2.Int64
4960
}
@@ -70,6 +81,10 @@ func OpFails() int64 {
7081
return cmdstats.fails.Get()
7182
}
7283

84+
func OpRedisErrors() int64 {
85+
return cmdstats.redis.errors.Get()
86+
}
87+
7388
func OpQPS() int64 {
7489
return cmdstats.qps.Get()
7590
}
@@ -125,21 +140,26 @@ func ResetStats() {
125140

126141
cmdstats.total.Set(0)
127142
cmdstats.fails.Set(0)
143+
cmdstats.redis.errors.Set(0)
128144
sessions.total.Set(sessions.alive.Get())
129145
}
130146

131147
func incrOpTotal(n int64) {
132148
cmdstats.total.Add(n)
133149
}
134150

135-
func incrOpFails() {
136-
cmdstats.fails.Incr()
137-
}
138-
139-
func incrOpStats(opstr string, calls int64, nsecs int64) {
140-
s := getOpStats(opstr, true)
141-
s.calls.Add(calls)
142-
s.nsecs.Add(nsecs)
151+
func incrOpStats(e *opStats) {
152+
s := getOpStats(e.opstr, true)
153+
s.calls.Add(e.calls.Swap(0))
154+
s.nsecs.Add(e.nsecs.Swap(0))
155+
if n := e.fails.Swap(0); n != 0 {
156+
s.fails.Add(n)
157+
cmdstats.fails.Add(n)
158+
}
159+
if n := e.redis.errors.Swap(0); n != 0 {
160+
s.redis.errors.Add(n)
161+
cmdstats.redis.errors.Add(n)
162+
}
143163
}
144164

145165
var sessions struct {

0 commit comments

Comments
 (0)