You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
2.1 KiB

  1. // Copyright 2014 The Gogs Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package log
  5. import (
  6. "encoding/json"
  7. "io"
  8. "log"
  9. "net"
  10. )
  11. // ConnWriter implements LoggerInterface.
  12. // it writes messages in keep-live tcp connection.
  13. type ConnWriter struct {
  14. lg *log.Logger
  15. innerWriter io.WriteCloser
  16. ReconnectOnMsg bool `json:"reconnectOnMsg"`
  17. Reconnect bool `json:"reconnect"`
  18. Net string `json:"net"`
  19. Addr string `json:"addr"`
  20. Level int `json:"level"`
  21. }
  22. // NewConn creates new ConnWrite returning as LoggerInterface.
  23. func NewConn() LoggerInterface {
  24. conn := new(ConnWriter)
  25. conn.Level = TRACE
  26. return conn
  27. }
  28. // Init inits connection writer with json config.
  29. // json config only need key "level".
  30. func (cw *ConnWriter) Init(jsonconfig string) error {
  31. return json.Unmarshal([]byte(jsonconfig), cw)
  32. }
  33. // WriteMsg writes message in connection.
  34. // if connection is down, try to re-connect.
  35. func (cw *ConnWriter) WriteMsg(msg string, skip, level int) error {
  36. if cw.Level > level {
  37. return nil
  38. }
  39. if cw.neededConnectOnMsg() {
  40. if err := cw.connect(); err != nil {
  41. return err
  42. }
  43. }
  44. if cw.ReconnectOnMsg {
  45. defer cw.innerWriter.Close()
  46. }
  47. cw.lg.Println(msg)
  48. return nil
  49. }
  50. // Flush no things for this implementation
  51. func (cw *ConnWriter) Flush() {
  52. }
  53. // Destroy destroy connection writer and close tcp listener.
  54. func (cw *ConnWriter) Destroy() {
  55. if cw.innerWriter == nil {
  56. return
  57. }
  58. cw.innerWriter.Close()
  59. }
  60. func (cw *ConnWriter) connect() error {
  61. if cw.innerWriter != nil {
  62. cw.innerWriter.Close()
  63. cw.innerWriter = nil
  64. }
  65. conn, err := net.Dial(cw.Net, cw.Addr)
  66. if err != nil {
  67. return err
  68. }
  69. if tcpConn, ok := conn.(*net.TCPConn); ok {
  70. tcpConn.SetKeepAlive(true)
  71. }
  72. cw.innerWriter = conn
  73. cw.lg = log.New(conn, "", log.Ldate|log.Ltime)
  74. return nil
  75. }
  76. func (cw *ConnWriter) neededConnectOnMsg() bool {
  77. if cw.Reconnect {
  78. cw.Reconnect = false
  79. return true
  80. }
  81. if cw.innerWriter == nil {
  82. return true
  83. }
  84. return cw.ReconnectOnMsg
  85. }
  86. func init() {
  87. Register("conn", NewConn)
  88. }