msg.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. package log
  2. import (
  3. "fmt"
  4. )
  5. // A wrapper around MsgImpl that provides some extra helpers to modify a Msg.
  6. type Msg struct {
  7. MsgImpl
  8. }
  9. func (m Msg) String() string {
  10. return m.Text()
  11. }
  12. func newMsg(text func() string) Msg {
  13. return Msg{rootMsgImpl{text}}
  14. }
  15. func Fmsg(format string, a ...interface{}) Msg {
  16. return newMsg(func() string { return fmt.Sprintf(format, a...) })
  17. }
  18. func Msgln(a ...interface{}) Msg {
  19. return newMsg(func() string {
  20. s := fmt.Sprintln(a...)
  21. // Sprintln adds a final newline, but we add that ourselves deeper in the logging code.
  22. return s[:len(s)-1]
  23. })
  24. }
  25. var Fstr = Fmsg
  26. func Str(s string) (m Msg) {
  27. return newMsg(func() string { return s })
  28. }
  29. type msgSkipCaller struct {
  30. MsgImpl
  31. skip int
  32. }
  33. func (me msgSkipCaller) Callers(skip int, pc []uintptr) int {
  34. return me.MsgImpl.Callers(skip+1+me.skip, pc)
  35. }
  36. func (m Msg) Skip(skip int) Msg {
  37. return Msg{msgSkipCaller{m.MsgImpl, skip}}
  38. }
  39. type item struct {
  40. key, value interface{}
  41. }
  42. // rename sink
  43. func (m Msg) Log(l Logger) Msg {
  44. l.Log(m.Skip(1))
  45. return m
  46. }
  47. func (m Msg) LogLevel(level Level, l Logger) Msg {
  48. l.LogLevel(level, m.Skip(1))
  49. return m
  50. }
  51. type msgWithValues struct {
  52. MsgImpl
  53. values []interface{}
  54. }
  55. func (me msgWithValues) Values(cb valueIterCallback) {
  56. for _, v := range me.values {
  57. if !cb(v) {
  58. return
  59. }
  60. }
  61. me.MsgImpl.Values(cb)
  62. }
  63. // TODO: What ordering should be applied to the values here, per MsgImpl.Values. For now they're
  64. // traversed in order of the slice.
  65. func (m Msg) WithValues(v ...interface{}) Msg {
  66. return Msg{msgWithValues{m.MsgImpl, v}}
  67. }
  68. func (m Msg) AddValues(v ...interface{}) Msg {
  69. return m.WithValues(v...)
  70. }
  71. func (m Msg) With(key, value interface{}) Msg {
  72. return m.WithValues(item{key, value})
  73. }
  74. func (m Msg) Add(key, value interface{}) Msg {
  75. return m.With(key, value)
  76. }
  77. //func (m Msg) SetLevel(level Level) Msg {
  78. // return m.With(levelKey, level)
  79. //}
  80. //func (m Msg) GetByKey(key interface{}) (value interface{}, ok bool) {
  81. // m.Values(func(i interface{}) bool {
  82. // if keyValue, isKeyValue := i.(item); isKeyValue && keyValue.key == key {
  83. // value = keyValue.value
  84. // ok = true
  85. // }
  86. // return !ok
  87. // })
  88. // return
  89. //}
  90. //func (m Msg) GetLevel() (l Level, ok bool) {
  91. // v, ok := m.GetByKey(levelKey)
  92. // if ok {
  93. // l = v.(Level)
  94. // }
  95. // return
  96. //}
  97. func (m Msg) HasValue(v interface{}) (has bool) {
  98. m.Values(func(i interface{}) bool {
  99. if i == v {
  100. has = true
  101. }
  102. return !has
  103. })
  104. return
  105. }
  106. func (m Msg) AddValue(v interface{}) Msg {
  107. return m.AddValues(v)
  108. }
  109. //func (m Msg) GetValueByType(p interface{}) bool {
  110. // pve := reflect.ValueOf(p).Elem()
  111. // t := pve.Type()
  112. // return !iter.All(func(i interface{}) bool {
  113. // iv := reflect.ValueOf(i)
  114. // if iv.Type() == t {
  115. // pve.Set(iv)
  116. // return false
  117. // }
  118. // return true
  119. // }, m.Values)
  120. //}
  121. func (m Msg) WithText(f func(Msg) string) Msg {
  122. return Msg{msgWithText{
  123. m,
  124. func() string { return f(m) },
  125. }}
  126. }
  127. type msgWithText struct {
  128. MsgImpl
  129. text func() string
  130. }
  131. func (me msgWithText) Text() string {
  132. return me.text()
  133. }