github.com/cs3org/reva/v2@v2.27.7/pkg/sysinfo/sysinfo.go (about)

     1  // Copyright 2018-2021 CERN
     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  // In applying this license, CERN does not waive the privileges and immunities
    16  // granted to it by virtue of its status as an Intergovernmental Organization
    17  // or submit itself to any jurisdiction.
    18  
    19  package sysinfo
    20  
    21  import (
    22  	"encoding/json"
    23  	"fmt"
    24  	"reflect"
    25  
    26  	"github.com/pkg/errors"
    27  )
    28  
    29  // SystemInformation stores general information about Reva and the system it's running on.
    30  type SystemInformation struct {
    31  	// Reva holds the main Reva information
    32  	Reva *RevaVersion `json:"reva"`
    33  }
    34  
    35  var (
    36  	// SysInfo provides global system information.
    37  	SysInfo = &SystemInformation{}
    38  )
    39  
    40  // ToJSON converts the system information to JSON.
    41  func (sysInfo *SystemInformation) ToJSON() (string, error) {
    42  	data, err := json.MarshalIndent(sysInfo, "", "\t")
    43  	if err != nil {
    44  		return "", fmt.Errorf("unable to marshal the system information: %v", err)
    45  	}
    46  	return string(data), nil
    47  }
    48  
    49  func replaceEmptyInfoValues(i interface{}) {
    50  	// Iterate over each field of the given interface and search for "empty" values
    51  	v := reflect.ValueOf(i).Elem()
    52  	for i := 0; i < v.NumField(); i++ {
    53  		// Check if the field is either a struct or a pointer to a struct; in that case, process the field recursively
    54  		f := v.Field(i)
    55  		if f.Kind() == reflect.Struct || (f.Kind() == reflect.Ptr && f.Elem().Kind() == reflect.Struct) {
    56  			replaceEmptyInfoValues(f.Interface())
    57  		} else if f.CanSet() { // Replace empty values with something more meaningful
    58  			if f.Kind() == reflect.String {
    59  				if len(f.String()) == 0 {
    60  					f.SetString("(Unknown)")
    61  				}
    62  			}
    63  		}
    64  	}
    65  }
    66  
    67  // InitSystemInfo initializes the global system information object and also registers the corresponding metrics.
    68  func InitSystemInfo(revaVersion *RevaVersion) error {
    69  	SysInfo = &SystemInformation{
    70  		Reva: revaVersion,
    71  	}
    72  
    73  	// Replace any empty values in the system information by more meaningful ones
    74  	replaceEmptyInfoValues(SysInfo)
    75  
    76  	// Register the system information metrics, as the necessary system info object has been filled out
    77  	if err := registerSystemInfoMetrics(); err != nil {
    78  		return errors.Wrap(err, "unable to register the system info metrics")
    79  	}
    80  
    81  	return nil
    82  }