1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package redis
16
17 import (
18 "bytes"
19 "fmt"
20 "log"
21 "time"
22 )
23
24 var (
25 _ ConnWithTimeout = (*loggingConn)(nil)
26 )
27
28
29 func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn {
30 if prefix != "" {
31 prefix = prefix + "."
32 }
33 return &loggingConn{conn, logger, prefix}
34 }
35
36 type loggingConn struct {
37 Conn
38 logger *log.Logger
39 prefix string
40 }
41
42 func (c *loggingConn) Close() error {
43 err := c.Conn.Close()
44 var buf bytes.Buffer
45 fmt.Fprintf(&buf, "%sClose() -> (%v)", c.prefix, err)
46 c.logger.Output(2, buf.String())
47 return err
48 }
49
50 func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) {
51 const chop = 32
52 switch v := v.(type) {
53 case []byte:
54 if len(v) > chop {
55 fmt.Fprintf(buf, "%q...", v[:chop])
56 } else {
57 fmt.Fprintf(buf, "%q", v)
58 }
59 case string:
60 if len(v) > chop {
61 fmt.Fprintf(buf, "%q...", v[:chop])
62 } else {
63 fmt.Fprintf(buf, "%q", v)
64 }
65 case []interface{}:
66 if len(v) == 0 {
67 buf.WriteString("[]")
68 } else {
69 sep := "["
70 fin := "]"
71 if len(v) > chop {
72 v = v[:chop]
73 fin = "...]"
74 }
75 for _, vv := range v {
76 buf.WriteString(sep)
77 c.printValue(buf, vv)
78 sep = ", "
79 }
80 buf.WriteString(fin)
81 }
82 default:
83 fmt.Fprint(buf, v)
84 }
85 }
86
87 func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) {
88 var buf bytes.Buffer
89 fmt.Fprintf(&buf, "%s%s(", c.prefix, method)
90 if method != "Receive" {
91 buf.WriteString(commandName)
92 for _, arg := range args {
93 buf.WriteString(", ")
94 c.printValue(&buf, arg)
95 }
96 }
97 buf.WriteString(") -> (")
98 if method != "Send" {
99 c.printValue(&buf, reply)
100 buf.WriteString(", ")
101 }
102 fmt.Fprintf(&buf, "%v)", err)
103 c.logger.Output(3, buf.String())
104 }
105
106 func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{}, error) {
107 reply, err := c.Conn.Do(commandName, args...)
108 c.print("Do", commandName, args, reply, err)
109 return reply, err
110 }
111
112 func (c *loggingConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (interface{}, error) {
113 reply, err := DoWithTimeout(c.Conn, timeout, commandName, args...)
114 c.print("DoWithTimeout", commandName, args, reply, err)
115 return reply, err
116 }
117
118 func (c *loggingConn) Send(commandName string, args ...interface{}) error {
119 err := c.Conn.Send(commandName, args...)
120 c.print("Send", commandName, args, nil, err)
121 return err
122 }
123
124 func (c *loggingConn) Receive() (interface{}, error) {
125 reply, err := c.Conn.Receive()
126 c.print("Receive", "", nil, reply, err)
127 return reply, err
128 }
129
130 func (c *loggingConn) ReceiveWithTimeout(timeout time.Duration) (interface{}, error) {
131 reply, err := ReceiveWithTimeout(c.Conn, timeout)
132 c.print("ReceiveWithTimeout", "", nil, reply, err)
133 return reply, err
134 }
135
View as plain text