github.com/Rookout/GoSDK@v0.1.48/pkg/processor/namespaces/namespace_serializer2.go (about) 1 package namespaces 2 3 import ( 4 "reflect" 5 "time" 6 "unicode/utf8" 7 "unsafe" 8 9 "github.com/Rookout/GoSDK/pkg/config" 10 pb "github.com/Rookout/GoSDK/pkg/protobuf" 11 "github.com/Rookout/GoSDK/pkg/rookoutErrors" 12 "github.com/Rookout/GoSDK/pkg/utils" 13 "google.golang.org/protobuf/types/known/timestamppb" 14 ) 15 16 type NamespaceSerializer2 struct { 17 *pb.Variant2 18 StringCache map[string]uint32 19 logErrors bool 20 currentDepth int 21 } 22 23 func NewNamespaceSerializer2(fromNamespace Namespace, logErrors bool) *NamespaceSerializer2 { 24 g := &NamespaceSerializer2{StringCache: make(map[string]uint32), Variant2: &pb.Variant2{}, logErrors: logErrors} 25 fromNamespace.Serialize(g) 26 return g 27 } 28 29 func (n *NamespaceSerializer2) spawn(fromNamespace Namespace) *NamespaceSerializer2 { 30 spawned := &NamespaceSerializer2{StringCache: n.StringCache, Variant2: &pb.Variant2{}, logErrors: n.logErrors, currentDepth: n.currentDepth + 1} 31 32 fromNamespace.Serialize(spawned) 33 return spawned 34 } 35 36 func (n *NamespaceSerializer2) spawnAtSameDepth(fromNamespace Namespace) *NamespaceSerializer2 { 37 spawned := &NamespaceSerializer2{StringCache: n.StringCache, Variant2: &pb.Variant2{}, logErrors: n.logErrors, currentDepth: n.currentDepth} 38 fromNamespace.Serialize(spawned) 39 return spawned 40 } 41 42 func (n *NamespaceSerializer2) dumpOriginalType(originalType string) { 43 n.OriginalTypeIndexInCache = n.getStringIndexInCache(originalType) 44 } 45 46 func (n *NamespaceSerializer2) dumpTypeMaxDepth(variantType uint32, maxDepthInt uint32) { 47 n.VariantTypeMaxDepth = uint32((variantType << 1) | maxDepthInt) 48 } 49 50 func (n *NamespaceSerializer2) dumpType(variantType pb.Variant_Type) { 51 maxDepthInt := n.VariantTypeMaxDepth & 1 52 n.dumpTypeMaxDepth(uint32(variantType), maxDepthInt) 53 } 54 55 func (n *NamespaceSerializer2) dumpMaxDepth(maxDepth bool) { 56 maxDepthInt := 0 57 if maxDepth { 58 maxDepthInt = 1 59 } 60 variantType := n.VariantTypeMaxDepth >> 1 61 n.dumpTypeMaxDepth(variantType, uint32(maxDepthInt)) 62 } 63 64 func (n *NamespaceSerializer2) getCurrentDepth() int { 65 return n.currentDepth 66 } 67 68 func (n *NamespaceSerializer2) getStringIndexInCache(s string) uint32 { 69 if i, ok := n.StringCache[s]; ok { 70 return i 71 } 72 73 n.StringCache[s] = uint32(len(n.StringCache)) 74 return n.StringCache[s] 75 } 76 77 func (n *NamespaceSerializer2) dumpUnsupported() { 78 n.dumpType(pb.Variant_VARIANT_UKNOWN_OBJECT) 79 } 80 81 func (n *NamespaceSerializer2) dumpComplex(c complex128) { 82 n.dumpType(pb.Variant_VARIANT_COMPLEX) 83 n.ComplexValue = &pb.Variant_Complex{Real: real(c), Imaginary: imag(c)} 84 } 85 86 func (n *NamespaceSerializer2) dumpFloat(f float64) { 87 n.dumpType(pb.Variant_VARIANT_DOUBLE) 88 n.DoubleValue = f 89 } 90 91 func (n *NamespaceSerializer2) dumpString(s string, config config.ObjectDumpConfig) { 92 if !utf8.ValidString(s) { 93 n.dumpBinary([]byte(s), config) 94 return 95 } 96 n.dumpType(pb.Variant_VARIANT_STRING) 97 n.OriginalSize = uint32(len(s)) 98 if len(s) > config.MaxString { 99 s = s[:config.MaxString] 100 } 101 n.BytesIndexInCache = n.getStringIndexInCache(s) 102 } 103 104 func (n *NamespaceSerializer2) dumpStringLen(stringLen int) { 105 n.OriginalSize = uint32(stringLen) 106 } 107 108 func (n *NamespaceSerializer2) dumpBinary(b []byte, config config.ObjectDumpConfig) { 109 n.dumpType(pb.Variant_VARIANT_BINARY) 110 n.OriginalSize = uint32(len(b)) 111 if len(b) > config.MaxString { 112 b = b[:config.MaxString] 113 } 114 n.BytesIndexInCache = n.getStringIndexInCache(string(b)) 115 } 116 117 func (n *NamespaceSerializer2) dumpInt(i int64) { 118 n.dumpType(pb.Variant_VARIANT_LONG) 119 n.LongValue = i 120 } 121 122 func (n *NamespaceSerializer2) dumpBool(b bool) { 123 n.dumpType(pb.Variant_VARIANT_INT) 124 if b { 125 n.LongValue = 1 126 } else { 127 n.LongValue = 0 128 } 129 } 130 131 func (n *NamespaceSerializer2) dumpTime(t time.Time, config config.ObjectDumpConfig) { 132 n.dumpType(pb.Variant_VARIANT_TIME) 133 n.TimeValue = timestamppb.New(t) 134 } 135 136 func (n *NamespaceSerializer2) dumpArray(getElem func(i int) (Namespace, bool), arrayLen int, config config.ObjectDumpConfig) { 137 n.dumpType(pb.Variant_VARIANT_LIST) 138 n.OriginalSize = uint32(arrayLen) 139 140 if n.getCurrentDepth() >= config.MaxCollectionDepth { 141 n.dumpMaxDepth(true) 142 return 143 } 144 145 for i := 0; i < arrayLen; i++ { 146 if i >= config.MaxWidth { 147 return 148 } 149 150 e, ok := getElem(i) 151 if !ok { 152 break 153 } 154 155 n.CollectionValues = append(n.CollectionValues, n.spawn(e).Variant2) 156 } 157 } 158 159 func (n *NamespaceSerializer2) dumpNamespace(getNamedValue func(i int) (string, Namespace), numOfValues int) { 160 n.dumpType(pb.Variant_VARIANT_NAMESPACE) 161 162 for i := 0; i < numOfValues; i++ { 163 name, value := getNamedValue(i) 164 n.AttributeNamesInCache = append(n.AttributeNamesInCache, n.getStringIndexInCache(name)) 165 n.AttributeValues = append(n.AttributeValues, n.spawnAtSameDepth(value).Variant2) 166 } 167 } 168 169 func (n *NamespaceSerializer2) dumpTraceback(getFrame func(i int) (int, string, string), tracebackLen int) { 170 n.dumpType(pb.Variant_VARIANT_TRACEBACK) 171 172 for i := 0; i < tracebackLen; i++ { 173 lineno, filename, functionName := getFrame(i) 174 n.CodeValues = append(n.CodeValues, &pb.Variant_CodeObject{ 175 Lineno: uint32(lineno), 176 FilenameIndexInCache: n.getStringIndexInCache(filename), 177 NameIndexInCache: n.getStringIndexInCache(functionName), 178 ModuleIndexInCache: n.getStringIndexInCache(filename), 179 }) 180 } 181 } 182 183 func (n *NamespaceSerializer2) dumpStruct(getField func(i int) (string, Namespace, bool), numOfFields int, config config.ObjectDumpConfig) { 184 n.dumpType(pb.Variant_VARIANT_OBJECT) 185 186 if n.getCurrentDepth()+1 >= config.MaxDepth { 187 n.dumpMaxDepth(true) 188 return 189 } 190 191 for i := 0; i < numOfFields; i++ { 192 fieldName, fieldValue, ok := getField(i) 193 if !ok { 194 continue 195 } 196 n.AttributeNamesInCache = append(n.AttributeNamesInCache, n.getStringIndexInCache(fieldName)) 197 n.AttributeValues = append(n.AttributeValues, n.spawn(fieldValue).Variant2) 198 } 199 } 200 201 func (n *NamespaceSerializer2) dumpMap(getKeyValue func(i int) (Namespace, Namespace, bool), mapLen int, config config.ObjectDumpConfig) { 202 n.dumpType(pb.Variant_VARIANT_MAP) 203 n.OriginalSize = uint32(mapLen) 204 205 if n.getCurrentDepth() >= config.MaxCollectionDepth { 206 n.dumpMaxDepth(true) 207 return 208 } 209 210 for i := 0; i < mapLen; i++ { 211 if i >= config.MaxWidth { 212 return 213 } 214 215 key, value, ok := getKeyValue(i) 216 if !ok { 217 continue 218 } 219 n.CollectionKeys = append(n.CollectionKeys, n.spawn(key).Variant2) 220 n.CollectionValues = append(n.CollectionValues, n.spawn(value).Variant2) 221 } 222 } 223 224 func (n *NamespaceSerializer2) dumpNil() { 225 n.dumpType(pb.Variant_VARIANT_NONE) 226 } 227 228 func (n *NamespaceSerializer2) dumpFunc(functionName string, filename string, lineno int) { 229 n.dumpType(pb.Variant_VARIANT_CODE_OBJECT) 230 n.CodeValues = append(n.CodeValues, &pb.Variant_CodeObject{ 231 NameIndexInCache: n.getStringIndexInCache(functionName), 232 ModuleIndexInCache: n.getStringIndexInCache(filename), 233 Lineno: uint32(lineno), 234 FilenameIndexInCache: n.getStringIndexInCache(filename), 235 }) 236 } 237 238 func (n *NamespaceSerializer2) dumpChan(value reflect.Value, config config.ObjectDumpConfig) { 239 n.dumpType(pb.Variant_VARIANT_LIST) 240 241 if n.getCurrentDepth() >= config.MaxCollectionDepth { 242 n.dumpMaxDepth(true) 243 return 244 } 245 246 addr := utils.UnsafePointer(value) 247 chanStruct := *(*hchan)(addr) 248 elemType := value.Type().Elem() 249 bufSize := value.Len() * int(elemType.Size()) 250 251 for i := 0; i < bufSize; i += int(elemType.Size()) { 252 if len(n.CollectionValues) >= config.MaxWidth { 253 return 254 } 255 256 ptr := unsafe.Pointer(uintptr(chanStruct.buf) + uintptr(i)) 257 val := reflect.NewAt(elemType, ptr).Elem() 258 valVariant := &NamespaceSerializer2{StringCache: n.StringCache, Variant2: &pb.Variant2{}, logErrors: n.logErrors, currentDepth: n.currentDepth + 1} 259 dumpValue(valVariant, val, config) 260 n.CollectionValues = append(n.CollectionValues, valVariant.Variant2) 261 } 262 } 263 264 func (n *NamespaceSerializer2) dumpRookoutError(r rookoutErrors.RookoutError) { 265 n.dumpType(pb.Variant_VARIANT_ERROR) 266 267 parameters := n.spawn(NewGoObjectNamespace(r.GetArguments())) 268 traceback := n.spawn(NewGoObjectNamespace(r.StackFrames())) 269 n.ErrorValue = &pb.Error2{ 270 Message: r.Error(), 271 Type: r.GetType(), 272 Parameters: parameters.Variant2, 273 Traceback: traceback.Variant2, 274 } 275 } 276 277 func (n *NamespaceSerializer2) dumpErrorMessage(msg string) { 278 n.dumpType(pb.Variant_VARIANT_ERROR) 279 n.ErrorValue = &pb.Error2{ 280 Message: msg, 281 } 282 } 283 284 func (n *NamespaceSerializer2) dumpEnum(desc string, ordinal int, _ string) { 285 n.dumpType(pb.Variant_VARIANT_ENUM) 286 n.BytesIndexInCache = n.getStringIndexInCache(desc) 287 n.LongValue = int64(ordinal) 288 }