tlog.app/go/tlog@v0.23.1/wire.go (about) 1 package tlog 2 3 import ( 4 "unicode/utf8" 5 _ "unsafe" 6 7 "github.com/nikandfor/hacked/low" 8 "tlog.app/go/loc" 9 10 "tlog.app/go/tlog/tlwire" 11 ) 12 13 type ( 14 RawMessage []byte 15 16 Modify []byte 17 18 Timestamp int64 19 20 FormatNext string 21 22 format struct { 23 Fmt string 24 Args []interface{} 25 } 26 ) 27 28 const KeyAuto = "" 29 30 var ( 31 Hidden = RawMessage{tlwire.Special | tlwire.Hidden} 32 None = RawMessage{tlwire.Special | tlwire.None} 33 Nil = RawMessage{tlwire.Special | tlwire.Nil} 34 Break = RawMessage{tlwire.Special | tlwire.Break} 35 NextAsHex = Modify{tlwire.Semantic | tlwire.Hex} 36 NextAsMessage = Modify{tlwire.Semantic | WireMessage} 37 NextAsType = FormatNext("%T") 38 ) 39 40 // Wire semantic tags. 41 const ( 42 WireLabel = tlwire.SemanticTlogBase + iota 43 WireID 44 WireMessage 45 WireEventKind 46 WireLogLevel 47 48 _ 49 _ 50 _ 51 _ 52 _ 53 54 SemanticUserBase 55 ) 56 57 var ( 58 e tlwire.Encoder 59 d tlwire.Decoder 60 ) 61 62 func AppendLabels(b []byte, kvs []interface{}) []byte { 63 const tag = tlwire.Semantic | WireLabel 64 65 w := len(b) 66 b = append(b, low.Spaces[:len(kvs)/2+1]...) 67 r := len(b) 68 69 b = AppendKVs(b, kvs) 70 71 for r < len(b) { 72 end := d.Skip(b, r) 73 74 w += copy(b[w:], b[r:end]) 75 r = end 76 77 end = d.Skip(b, r) 78 79 if b[r] != tag { 80 b[w] = tag 81 w++ 82 } 83 84 w += copy(b[w:], b[r:end]) 85 r = end 86 } 87 88 return b[:w] 89 } 90 91 func AppendKVs(b []byte, kvs []interface{}) []byte { 92 return appendKVs0(b, kvs) 93 } 94 95 func NextIs(semantic int) Modify { 96 return Modify(tlwire.LowEncoder{}.AppendTag(nil, tlwire.Semantic, semantic)) 97 } 98 99 func RawTag(tag byte, sub int) RawMessage { 100 return RawMessage(tlwire.LowEncoder{}.AppendTag(nil, tag, sub)) 101 } 102 103 func Special(value int) RawMessage { 104 return RawMessage(tlwire.LowEncoder{}.AppendTag(nil, tlwire.Special, value)) 105 } 106 107 //go:linkname appendKVs0 tlog.app/go/tlog.appendKVs 108 //go:noescape 109 func appendKVs0(b []byte, kvs []interface{}) []byte 110 111 func init() { // prevent deadcode warnings 112 appendKVs(nil, nil) 113 } 114 115 func appendKVs(b []byte, kvs []interface{}) []byte { 116 for i := 0; i < len(kvs); { 117 var k string 118 119 switch el := kvs[i].(type) { 120 case string: 121 k = el 122 123 if k == KeyAuto { 124 k = autoKey(kvs[i:]) 125 } 126 127 i++ 128 case RawMessage: 129 b = append(b, el...) 130 i++ 131 continue 132 case tlwire.TlogAppender: 133 b = el.TlogAppend(b) 134 i++ 135 continue 136 default: 137 k = "MISSING_KEY" 138 } 139 140 b = e.AppendString(b, k) 141 142 value: 143 if i == len(kvs) { 144 b = append(b, tlwire.Special|tlwire.Undefined) 145 break 146 } 147 148 switch v := kvs[i].(type) { 149 case string: 150 b = e.AppendString(b, v) 151 case int: 152 b = e.AppendInt(b, v) 153 case RawMessage: 154 b = append(b, v...) 155 case Modify: 156 b = append(b, v...) 157 i++ 158 159 goto value 160 case FormatNext: 161 i++ 162 if i == len(kvs) { 163 b = append(b, tlwire.Special|tlwire.Undefined) 164 break 165 } 166 167 b = e.AppendFormat(b, string(v), kvs[i]) 168 default: 169 b = e.AppendValue(b, v) 170 } 171 172 i++ 173 } 174 175 return b 176 } 177 178 func autoKey(kvs []interface{}) (k string) { 179 if len(kvs) == 1 { 180 return "MISSING_VALUE" 181 } 182 183 switch kvs[1].(type) { 184 // case Message: 185 // k = KeyMessage 186 case ID: 187 k = KeySpan 188 case LogLevel: 189 k = KeyLogLevel 190 case EventKind: 191 k = KeyEventKind 192 case loc.PC: 193 k = KeyCaller 194 case loc.PCs: 195 k = KeyCaller 196 default: 197 k = "UNSUPPORTED_AUTO_KEY" 198 } 199 200 return 201 } 202 203 func (ek EventKind) String() string { 204 return string(ek) 205 } 206 207 func (id ID) TlogAppend(b []byte) []byte { 208 b = append(b, tlwire.Semantic|WireID) 209 return e.AppendBytes(b, id[:]) 210 } 211 212 func (id *ID) TlogParse(p []byte, i int) int { 213 if p[i] != tlwire.Semantic|WireID { 214 panic("not an id") 215 } 216 217 i++ 218 219 if p[i] != tlwire.Bytes|16 { 220 panic("not an id") 221 } 222 223 i++ 224 225 i += copy((*id)[:], p[i:]) 226 227 return i 228 } 229 230 func (ek EventKind) TlogAppend(b []byte) []byte { 231 b = append(b, tlwire.Semantic|WireEventKind) 232 return e.AppendString(b, string(ek)) 233 } 234 235 func (ek *EventKind) TlogParse(p []byte, i int) int { 236 if p[i] != tlwire.Semantic|WireEventKind { 237 panic("not an event type") 238 } 239 240 i++ 241 242 v, i := d.Bytes(p, i) 243 244 r, w := utf8.DecodeRune(v) 245 if w == utf8.RuneError || w != len(v) { 246 panic("bad rune") 247 } 248 249 *ek = EventKind(r) 250 251 return i 252 } 253 254 func (l LogLevel) TlogAppend(b []byte) []byte { 255 b = append(b, tlwire.Semantic|WireLogLevel) 256 return e.AppendInt(b, int(l)) 257 } 258 259 func (l *LogLevel) TlogParse(p []byte, i int) int { 260 if p[i] != tlwire.Semantic|WireLogLevel { 261 panic("not a log level") 262 } 263 264 i++ 265 266 v, i := d.Signed(p, i) 267 268 *l = LogLevel(v) 269 270 return i 271 } 272 273 func (r RawMessage) TlogAppend(b []byte) []byte { 274 return append(b, r...) 275 } 276 277 func (r *RawMessage) TlogParse(p []byte, st int) (i int) { 278 i = d.Skip(p, st) 279 *r = append((*r)[:0], p[st:i]...) 280 return i 281 }