github.com/netdata/go.d.plugin@v0.58.1/modules/hdfs/collect.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package hdfs
     4  
     5  import (
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  	"strings"
    10  
    11  	"github.com/netdata/go.d.plugin/pkg/stm"
    12  )
    13  
    14  type (
    15  	rawData map[string]json.RawMessage
    16  	rawJMX  struct {
    17  		Beans []rawData
    18  	}
    19  )
    20  
    21  func (r rawJMX) isEmpty() bool {
    22  	return len(r.Beans) == 0
    23  }
    24  
    25  func (r rawJMX) find(f func(rawData) bool) rawData {
    26  	for _, v := range r.Beans {
    27  		if f(v) {
    28  			return v
    29  		}
    30  	}
    31  	return nil
    32  }
    33  
    34  func (r rawJMX) findJvm() rawData {
    35  	f := func(data rawData) bool { return string(data["modelerType"]) == "\"JvmMetrics\"" }
    36  	return r.find(f)
    37  }
    38  
    39  func (r rawJMX) findRPCActivity() rawData {
    40  	f := func(data rawData) bool { return strings.HasPrefix(string(data["modelerType"]), "\"RpcActivityForPort") }
    41  	return r.find(f)
    42  }
    43  
    44  func (r rawJMX) findFSNameSystem() rawData {
    45  	f := func(data rawData) bool { return string(data["modelerType"]) == "\"FSNamesystem\"" }
    46  	return r.find(f)
    47  }
    48  
    49  func (r rawJMX) findFSDatasetState() rawData {
    50  	f := func(data rawData) bool { return string(data["modelerType"]) == "\"FSDatasetState\"" }
    51  	return r.find(f)
    52  }
    53  
    54  func (r rawJMX) findDataNodeActivity() rawData {
    55  	f := func(data rawData) bool { return strings.HasPrefix(string(data["modelerType"]), "\"DataNodeActivity") }
    56  	return r.find(f)
    57  }
    58  
    59  func (h *HDFS) collect() (map[string]int64, error) {
    60  	var raw rawJMX
    61  	err := h.client.doOKWithDecodeJSON(&raw)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	if raw.isEmpty() {
    67  		return nil, errors.New("empty response")
    68  	}
    69  
    70  	mx := h.collectRawJMX(raw)
    71  
    72  	return stm.ToMap(mx), nil
    73  }
    74  
    75  func (h HDFS) collectRawJMX(raw rawJMX) *metrics {
    76  	var mx metrics
    77  	switch h.nodeType {
    78  	default:
    79  		panic(fmt.Sprintf("unsupported node type : '%s'", h.nodeType))
    80  	case nameNodeType:
    81  		h.collectNameNode(&mx, raw)
    82  	case dataNodeType:
    83  		h.collectDataNode(&mx, raw)
    84  	}
    85  	return &mx
    86  }
    87  
    88  func (h HDFS) collectNameNode(mx *metrics, raw rawJMX) {
    89  	err := h.collectJVM(mx, raw)
    90  	if err != nil {
    91  		h.Debugf("error on collecting jvm : %v", err)
    92  	}
    93  
    94  	err = h.collectRPCActivity(mx, raw)
    95  	if err != nil {
    96  		h.Debugf("error on collecting rpc activity : %v", err)
    97  	}
    98  
    99  	err = h.collectFSNameSystem(mx, raw)
   100  	if err != nil {
   101  		h.Debugf("error on collecting fs name system : %v", err)
   102  	}
   103  }
   104  
   105  func (h HDFS) collectDataNode(mx *metrics, raw rawJMX) {
   106  	err := h.collectJVM(mx, raw)
   107  	if err != nil {
   108  		h.Debugf("error on collecting jvm : %v", err)
   109  	}
   110  
   111  	err = h.collectRPCActivity(mx, raw)
   112  	if err != nil {
   113  		h.Debugf("error on collecting rpc activity : %v", err)
   114  	}
   115  
   116  	err = h.collectFSDatasetState(mx, raw)
   117  	if err != nil {
   118  		h.Debugf("error on collecting fs dataset state : %v", err)
   119  	}
   120  
   121  	err = h.collectDataNodeActivity(mx, raw)
   122  	if err != nil {
   123  		h.Debugf("error on collecting datanode activity state : %v", err)
   124  	}
   125  }
   126  
   127  func (h HDFS) collectJVM(mx *metrics, raw rawJMX) error {
   128  	v := raw.findJvm()
   129  	if v == nil {
   130  		return nil
   131  	}
   132  
   133  	var jvm jvmMetrics
   134  	err := writeJSONTo(&jvm, v)
   135  	if err != nil {
   136  		return err
   137  	}
   138  
   139  	mx.Jvm = &jvm
   140  	return nil
   141  }
   142  
   143  func (h HDFS) collectRPCActivity(mx *metrics, raw rawJMX) error {
   144  	v := raw.findRPCActivity()
   145  	if v == nil {
   146  		return nil
   147  	}
   148  
   149  	var rpc rpcActivityMetrics
   150  	err := writeJSONTo(&rpc, v)
   151  	if err != nil {
   152  		return err
   153  	}
   154  
   155  	mx.Rpc = &rpc
   156  	return nil
   157  }
   158  
   159  func (h HDFS) collectFSNameSystem(mx *metrics, raw rawJMX) error {
   160  	v := raw.findFSNameSystem()
   161  	if v == nil {
   162  		return nil
   163  	}
   164  
   165  	var fs fsNameSystemMetrics
   166  	err := writeJSONTo(&fs, v)
   167  	if err != nil {
   168  		return err
   169  	}
   170  
   171  	fs.CapacityUsed = fs.CapacityDfsUsed + fs.CapacityUsedNonDFS
   172  
   173  	mx.FSNameSystem = &fs
   174  	return nil
   175  }
   176  
   177  func (h HDFS) collectFSDatasetState(mx *metrics, raw rawJMX) error {
   178  	v := raw.findFSDatasetState()
   179  	if v == nil {
   180  		return nil
   181  	}
   182  
   183  	var fs fsDatasetStateMetrics
   184  	err := writeJSONTo(&fs, v)
   185  	if err != nil {
   186  		return err
   187  	}
   188  
   189  	fs.CapacityUsed = fs.Capacity - fs.Remaining
   190  	fs.CapacityUsedNonDFS = fs.CapacityUsed - fs.DfsUsed
   191  
   192  	mx.FSDatasetState = &fs
   193  	return nil
   194  }
   195  
   196  func (h HDFS) collectDataNodeActivity(mx *metrics, raw rawJMX) error {
   197  	v := raw.findDataNodeActivity()
   198  	if v == nil {
   199  		return nil
   200  	}
   201  
   202  	var dna dataNodeActivityMetrics
   203  	err := writeJSONTo(&dna, v)
   204  	if err != nil {
   205  		return err
   206  	}
   207  
   208  	mx.DataNodeActivity = &dna
   209  	return nil
   210  }
   211  
   212  func writeJSONTo(dst interface{}, src interface{}) error {
   213  	b, err := json.Marshal(src)
   214  	if err != nil {
   215  		return err
   216  	}
   217  	return json.Unmarshal(b, dst)
   218  }