github.com/matrixorigin/matrixone@v1.2.0/pkg/perfcounter/http.go (about)

     1  // Copyright 2023 Matrix Origin
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package perfcounter
    16  
    17  import (
    18  	"fmt"
    19  	"github.com/matrixorigin/matrixone/pkg/util/metric/stats"
    20  	"io"
    21  	"net/http"
    22  	"reflect"
    23  	"sort"
    24  	"sync/atomic"
    25  )
    26  
    27  func (c *CounterSet) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    28  	fmt.Fprintf(w, `
    29    <style>
    30    table, th, td {
    31      border: 1px solid;
    32      border-collapse: collapse;
    33      font-family: monospace, monospace;
    34    }
    35    </style>
    36    `)
    37  
    38  	v := reflect.ValueOf(c)
    39  	format(w, v, v.Type())
    40  }
    41  
    42  func format(w io.Writer, v reflect.Value, t reflect.Type) {
    43  	switch val := v.Interface().(type) {
    44  	case atomic.Int64:
    45  		fmt.Fprintf(w, "%v", val.Load())
    46  	case stats.Counter:
    47  		fmt.Fprintf(w, "%v", val.Load())
    48  
    49  	default:
    50  		switch t.Kind() {
    51  		case reflect.Struct:
    52  			formatStruct(w, v, t)
    53  		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
    54  			fmt.Fprintf(w, "%v", v.Int())
    55  		case reflect.Ptr, reflect.Interface:
    56  			format(w, v.Elem(), t.Elem())
    57  		case reflect.Map:
    58  			formatMap(w, v, t)
    59  		case reflect.String:
    60  			fmt.Fprint(w, v.String())
    61  		default:
    62  			panic(fmt.Sprintf("unknown kind: %v", t.Kind()))
    63  		}
    64  	}
    65  }
    66  
    67  func formatStruct(w io.Writer, v reflect.Value, t reflect.Type) {
    68  	fmt.Fprintf(w, "<table>")
    69  	defer fmt.Fprintf(w, "</table>")
    70  	for i, l := 0, t.NumField(); i < l; i++ {
    71  		fieldValue := v.Field(i)
    72  		if fieldValue.IsZero() {
    73  			continue
    74  		}
    75  		field := t.Field(i)
    76  		fmt.Fprintf(w, "<tr>")
    77  		fmt.Fprintf(w, "<td>%s</td>", field.Name)
    78  		fmt.Fprintf(w, "<td>")
    79  		format(w, fieldValue, fieldValue.Type())
    80  		fmt.Fprintf(w, "</td>")
    81  		fmt.Fprintf(w, "</tr>")
    82  	}
    83  }
    84  
    85  func formatMap(w io.Writer, v reflect.Value, t reflect.Type) {
    86  	fmt.Fprintf(w, "<table>")
    87  	defer fmt.Fprintf(w, "</table>")
    88  
    89  	if t.Key().Kind() == reflect.String {
    90  		keyValues := v.MapKeys()
    91  		keys := make([]string, 0, v.Len())
    92  		for _, keyValue := range keyValues {
    93  			keys = append(keys, keyValue.String())
    94  		}
    95  		sort.Strings(keys)
    96  		for _, key := range keys {
    97  			fmt.Fprintf(w, "<tr>")
    98  			fmt.Fprint(w, "<td>")
    99  			fmt.Fprint(w, key)
   100  			fmt.Fprint(w, "</td>")
   101  			value := v.MapIndex(reflect.ValueOf(key))
   102  			fmt.Fprint(w, "<td>")
   103  			format(w, value, value.Type())
   104  			fmt.Fprint(w, "</td>")
   105  			fmt.Fprint(w, "</tr>")
   106  		}
   107  
   108  	} else {
   109  		iter := v.MapRange()
   110  		for iter.Next() {
   111  			value := iter.Value()
   112  			if value.IsZero() {
   113  				continue
   114  			}
   115  			key := iter.Key()
   116  			fmt.Fprintf(w, "<tr>")
   117  			fmt.Fprintf(w, "<td>")
   118  			format(w, key, key.Type())
   119  			fmt.Fprintf(w, "</td>")
   120  			fmt.Fprintf(w, "<td>")
   121  			format(w, value, value.Type())
   122  			fmt.Fprintf(w, "</td>")
   123  			fmt.Fprintf(w, "</tr>")
   124  		}
   125  	}
   126  }