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.

104 lines
2.0 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. // create new ConnWrite returning as LoggerInterface.
  23. func NewConn() LoggerInterface {
  24. conn := new(ConnWriter)
  25. conn.Level = TRACE
  26. return conn
  27. }
  28. // init 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. // write 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.neddedConnectOnMsg() {
  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. func (_ *ConnWriter) Flush() {
  51. }
  52. // destroy connection writer and close tcp listener.
  53. func (cw *ConnWriter) Destroy() {
  54. if cw.innerWriter == nil {
  55. return
  56. }
  57. cw.innerWriter.Close()
  58. }
  59. func (cw *ConnWriter) connect() error {
  60. if cw.innerWriter != nil {
  61. cw.innerWriter.Close()
  62. cw.innerWriter = nil
  63. }
  64. conn, err := net.Dial(cw.Net, cw.Addr)
  65. if err != nil {
  66. return err
  67. }
  68. if tcpConn, ok := conn.(*net.TCPConn); ok {
  69. tcpConn.SetKeepAlive(true)
  70. }
  71. cw.innerWriter = conn
  72. cw.lg = log.New(conn, "", log.Ldate|log.Ltime)
  73. return nil
  74. }
  75. func (cw *ConnWriter) neddedConnectOnMsg() bool {
  76. if cw.Reconnect {
  77. cw.Reconnect = false
  78. return true
  79. }
  80. if cw.innerWriter == nil {
  81. return true
  82. }
  83. return cw.ReconnectOnMsg
  84. }
  85. func init() {
  86. Register("conn", NewConn)
  87. }