dubbo.apache.org/dubbo-go/v3@v3.1.1/xds/utils/pretty/pretty.go (about)

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   * contributor license agreements.  See the NOTICE file distributed with
     4   * this work for additional information regarding copyright ownership.
     5   * The ASF licenses this file to You under the Apache License, Version 2.0
     6   * (the "License"); you may not use this file except in compliance with
     7   * the License.  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   *
    20   * Copyright 2021 gRPC authors.
    21   *
    22   */
    23  
    24  // Package pretty defines helper functions to pretty-print structs for logging.
    25  package pretty
    26  
    27  import (
    28  	"bytes"
    29  	"encoding/json"
    30  	"fmt"
    31  )
    32  
    33  import (
    34  	"github.com/golang/protobuf/jsonpb"
    35  	protov1 "github.com/golang/protobuf/proto"
    36  
    37  	"google.golang.org/protobuf/encoding/protojson"
    38  
    39  	protov2 "google.golang.org/protobuf/proto"
    40  )
    41  
    42  const jsonIndent = "  "
    43  
    44  // ToJSON marshals the input into a json string.
    45  //
    46  // If marshal fails, it falls back to fmt.Sprintf("%+v").
    47  func ToJSON(e interface{}) string {
    48  	switch ee := e.(type) {
    49  	case protov1.Message:
    50  		mm := jsonpb.Marshaler{Indent: jsonIndent}
    51  		ret, err := mm.MarshalToString(ee)
    52  		if err != nil {
    53  			// This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2
    54  			// messages are not imported, and this will fail because the message
    55  			// is not found.
    56  			return fmt.Sprintf("%+v", ee)
    57  		}
    58  		return ret
    59  	case protov2.Message:
    60  		mm := protojson.MarshalOptions{
    61  			Multiline: true,
    62  			Indent:    jsonIndent,
    63  		}
    64  		ret, err := mm.Marshal(ee)
    65  		if err != nil {
    66  			// This may fail for proto.Anys, e.g. for xDS v2, LDS, the v2
    67  			// messages are not imported, and this will fail because the message
    68  			// is not found.
    69  			return fmt.Sprintf("%+v", ee)
    70  		}
    71  		return string(ret)
    72  	default:
    73  		ret, err := json.MarshalIndent(ee, "", jsonIndent)
    74  		if err != nil {
    75  			return fmt.Sprintf("%+v", ee)
    76  		}
    77  		return string(ret)
    78  	}
    79  }
    80  
    81  // FormatJSON formats the input json bytes with indentation.
    82  //
    83  // If Indent fails, it returns the unchanged input as string.
    84  func FormatJSON(b []byte) string {
    85  	var out bytes.Buffer
    86  	err := json.Indent(&out, b, "", jsonIndent)
    87  	if err != nil {
    88  		return string(b)
    89  	}
    90  	return out.String()
    91  }