google.golang.org/grpc@v1.62.1/internal/pretty/pretty.go (about) 1 /* 2 * 3 * Copyright 2021 gRPC authors. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 19 // Package pretty defines helper functions to pretty-print structs for logging. 20 package pretty 21 22 import ( 23 "bytes" 24 "encoding/json" 25 "fmt" 26 27 protov1 "github.com/golang/protobuf/proto" 28 "google.golang.org/protobuf/encoding/protojson" 29 protov2 "google.golang.org/protobuf/proto" 30 ) 31 32 const jsonIndent = " " 33 34 // ToJSON marshals the input into a json string. 35 // 36 // If marshal fails, it falls back to fmt.Sprintf("%+v"). 37 func ToJSON(e any) string { 38 switch ee := e.(type) { 39 case protov1.Message: 40 mm := protojson.MarshalOptions{Indent: jsonIndent} 41 ret, err := mm.Marshal(protov1.MessageV2(ee)) 42 if err != nil { 43 // This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2 44 // messages are not imported, and this will fail because the message 45 // is not found. 46 return fmt.Sprintf("%+v", ee) 47 } 48 return string(ret) 49 case protov2.Message: 50 mm := protojson.MarshalOptions{ 51 Multiline: true, 52 Indent: jsonIndent, 53 } 54 ret, err := mm.Marshal(ee) 55 if err != nil { 56 // This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2 57 // messages are not imported, and this will fail because the message 58 // is not found. 59 return fmt.Sprintf("%+v", ee) 60 } 61 return string(ret) 62 default: 63 ret, err := json.MarshalIndent(ee, "", jsonIndent) 64 if err != nil { 65 return fmt.Sprintf("%+v", ee) 66 } 67 return string(ret) 68 } 69 } 70 71 // FormatJSON formats the input json bytes with indentation. 72 // 73 // If Indent fails, it returns the unchanged input as string. 74 func FormatJSON(b []byte) string { 75 var out bytes.Buffer 76 err := json.Indent(&out, b, "", jsonIndent) 77 if err != nil { 78 return string(b) 79 } 80 return out.String() 81 }