log.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Copyright 2012 Gary Burd
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License"): you may
  4. // not use this file except in compliance with the License. You may obtain
  5. // a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  11. // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  12. // License for the specific language governing permissions and limitations
  13. // under the License.
  14. package redis
  15. import (
  16. "bytes"
  17. "fmt"
  18. "log"
  19. "time"
  20. )
  21. var (
  22. _ ConnWithTimeout = (*loggingConn)(nil)
  23. )
  24. // NewLoggingConn returns a logging wrapper around a connection.
  25. func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn {
  26. if prefix != "" {
  27. prefix = prefix + "."
  28. }
  29. return &loggingConn{conn, logger, prefix}
  30. }
  31. type loggingConn struct {
  32. Conn
  33. logger *log.Logger
  34. prefix string
  35. }
  36. func (c *loggingConn) Close() error {
  37. err := c.Conn.Close()
  38. var buf bytes.Buffer
  39. fmt.Fprintf(&buf, "%sClose() -> (%v)", c.prefix, err)
  40. c.logger.Output(2, buf.String())
  41. return err
  42. }
  43. func (c *loggingConn) printValue(buf *bytes.Buffer, v interface{}) {
  44. const chop = 32
  45. switch v := v.(type) {
  46. case []byte:
  47. if len(v) > chop {
  48. fmt.Fprintf(buf, "%q...", v[:chop])
  49. } else {
  50. fmt.Fprintf(buf, "%q", v)
  51. }
  52. case string:
  53. if len(v) > chop {
  54. fmt.Fprintf(buf, "%q...", v[:chop])
  55. } else {
  56. fmt.Fprintf(buf, "%q", v)
  57. }
  58. case []interface{}:
  59. if len(v) == 0 {
  60. buf.WriteString("[]")
  61. } else {
  62. sep := "["
  63. fin := "]"
  64. if len(v) > chop {
  65. v = v[:chop]
  66. fin = "...]"
  67. }
  68. for _, vv := range v {
  69. buf.WriteString(sep)
  70. c.printValue(buf, vv)
  71. sep = ", "
  72. }
  73. buf.WriteString(fin)
  74. }
  75. default:
  76. fmt.Fprint(buf, v)
  77. }
  78. }
  79. func (c *loggingConn) print(method, commandName string, args []interface{}, reply interface{}, err error) {
  80. var buf bytes.Buffer
  81. fmt.Fprintf(&buf, "%s%s(", c.prefix, method)
  82. if method != "Receive" {
  83. buf.WriteString(commandName)
  84. for _, arg := range args {
  85. buf.WriteString(", ")
  86. c.printValue(&buf, arg)
  87. }
  88. }
  89. buf.WriteString(") -> (")
  90. if method != "Send" {
  91. c.printValue(&buf, reply)
  92. buf.WriteString(", ")
  93. }
  94. fmt.Fprintf(&buf, "%v)", err)
  95. c.logger.Output(3, buf.String())
  96. }
  97. func (c *loggingConn) Do(commandName string, args ...interface{}) (interface{}, error) {
  98. reply, err := c.Conn.Do(commandName, args...)
  99. c.print("Do", commandName, args, reply, err)
  100. return reply, err
  101. }
  102. func (c *loggingConn) DoWithTimeout(timeout time.Duration, commandName string, args ...interface{}) (interface{}, error) {
  103. reply, err := DoWithTimeout(c.Conn, timeout, commandName, args...)
  104. c.print("DoWithTimeout", commandName, args, reply, err)
  105. return reply, err
  106. }
  107. func (c *loggingConn) Send(commandName string, args ...interface{}) error {
  108. err := c.Conn.Send(commandName, args...)
  109. c.print("Send", commandName, args, nil, err)
  110. return err
  111. }
  112. func (c *loggingConn) Receive() (interface{}, error) {
  113. reply, err := c.Conn.Receive()
  114. c.print("Receive", "", nil, reply, err)
  115. return reply, err
  116. }
  117. func (c *loggingConn) ReceiveWithTimeout(timeout time.Duration) (interface{}, error) {
  118. reply, err := ReceiveWithTimeout(c.Conn, timeout)
  119. c.print("ReceiveWithTimeout", "", nil, reply, err)
  120. return reply, err
  121. }