github.com/netdata/go.d.plugin@v0.58.1/agent/netdataapi/api.go (about)

     1  // SPDX-License-Identifier: GPL-3.0-or-later
     2  
     3  package netdataapi
     4  
     5  import (
     6  	"bytes"
     7  	"fmt"
     8  	"io"
     9  	"strconv"
    10  )
    11  
    12  type (
    13  	// API implements Netdata external plugins API.
    14  	// https://learn.netdata.cloud/docs/agent/collectors/plugins.d#the-output-of-the-plugin
    15  	API struct {
    16  		io.Writer
    17  	}
    18  )
    19  
    20  const quotes = "' '"
    21  
    22  var (
    23  	end          = []byte("END\n\n")
    24  	clabelCommit = []byte("CLABEL_COMMIT\n")
    25  	newLine      = []byte("\n")
    26  )
    27  
    28  func New(w io.Writer) *API { return &API{w} }
    29  
    30  // CHART  creates or update a chart.
    31  func (a *API) CHART(
    32  	typeID string,
    33  	ID string,
    34  	name string,
    35  	title string,
    36  	units string,
    37  	family string,
    38  	context string,
    39  	chartType string,
    40  	priority int,
    41  	updateEvery int,
    42  	options string,
    43  	plugin string,
    44  	module string) error {
    45  	_, err := a.Write([]byte("CHART " + "'" +
    46  		typeID + "." + ID + quotes +
    47  		name + quotes +
    48  		title + quotes +
    49  		units + quotes +
    50  		family + quotes +
    51  		context + quotes +
    52  		chartType + quotes +
    53  		strconv.Itoa(priority) + quotes +
    54  		strconv.Itoa(updateEvery) + quotes +
    55  		options + quotes +
    56  		plugin + quotes +
    57  		module + "'\n"))
    58  	return err
    59  }
    60  
    61  // DIMENSION adds or update a dimension to the chart just created.
    62  func (a *API) DIMENSION(
    63  	ID string,
    64  	name string,
    65  	algorithm string,
    66  	multiplier int,
    67  	divisor int,
    68  	options string) error {
    69  	_, err := a.Write([]byte("DIMENSION '" +
    70  		ID + quotes +
    71  		name + quotes +
    72  		algorithm + quotes +
    73  		strconv.Itoa(multiplier) + quotes +
    74  		strconv.Itoa(divisor) + quotes +
    75  		options + "'\n"))
    76  	return err
    77  }
    78  
    79  // CLABEL adds or update a label to the chart.
    80  func (a *API) CLABEL(key, value string, source int) error {
    81  	_, err := a.Write([]byte("CLABEL '" +
    82  		key + quotes +
    83  		value + quotes +
    84  		strconv.Itoa(source) + "'\n"))
    85  	return err
    86  }
    87  
    88  // CLABELCOMMIT adds labels to the chart. Should be called after one or more CLABEL.
    89  func (a *API) CLABELCOMMIT() error {
    90  	_, err := a.Write(clabelCommit)
    91  	return err
    92  }
    93  
    94  // BEGIN initializes data collection for a chart.
    95  func (a *API) BEGIN(typeID string, ID string, msSince int) (err error) {
    96  	if msSince > 0 {
    97  		_, err = a.Write([]byte("BEGIN " + "'" + typeID + "." + ID + "' " + strconv.Itoa(msSince) + "\n"))
    98  	} else {
    99  		_, err = a.Write([]byte("BEGIN " + "'" + typeID + "." + ID + "'\n"))
   100  	}
   101  	return err
   102  }
   103  
   104  // SET sets the value of a dimension for the initialized chart.
   105  func (a *API) SET(ID string, value int64) error {
   106  	_, err := a.Write([]byte("SET '" + ID + "' = " + strconv.FormatInt(value, 10) + "\n"))
   107  	return err
   108  }
   109  
   110  // SETEMPTY sets the empty value of a dimension for the initialized chart.
   111  func (a *API) SETEMPTY(ID string) error {
   112  	_, err := a.Write([]byte("SET '" + ID + "' = \n"))
   113  	return err
   114  }
   115  
   116  // VARIABLE sets the value of a CHART scope variable for the initialized chart.
   117  func (a *API) VARIABLE(ID string, value int64) error {
   118  	_, err := a.Write([]byte("VARIABLE CHART '" + ID + "' = " + strconv.FormatInt(value, 10) + "\n"))
   119  	return err
   120  }
   121  
   122  // END completes data collection for the initialized chart.
   123  func (a *API) END() error {
   124  	_, err := a.Write(end)
   125  	return err
   126  }
   127  
   128  // DISABLE disables this plugin. This will prevent Netdata from restarting the plugin.
   129  func (a *API) DISABLE() error {
   130  	_, err := a.Write([]byte("DISABLE\n"))
   131  	return err
   132  }
   133  
   134  // EMPTYLINE writes an empty line.
   135  func (a *API) EMPTYLINE() error {
   136  	_, err := a.Write(newLine)
   137  	return err
   138  }
   139  
   140  func (a *API) HOSTINFO(guid, hostname string, labels map[string]string) error {
   141  	if err := a.HOSTDEFINE(guid, hostname); err != nil {
   142  		return err
   143  	}
   144  	for k, v := range labels {
   145  		if err := a.HOSTLABEL(k, v); err != nil {
   146  			return err
   147  		}
   148  	}
   149  	return a.HOSTDEFINEEND()
   150  }
   151  
   152  func (a *API) HOSTDEFINE(guid, hostname string) error {
   153  	_, err := fmt.Fprintf(a, "HOST_DEFINE '%s' '%s'\n", guid, hostname)
   154  	return err
   155  }
   156  
   157  func (a *API) HOSTLABEL(name, value string) error {
   158  	_, err := fmt.Fprintf(a, "HOST_LABEL '%s' '%s'\n", name, value)
   159  	return err
   160  }
   161  
   162  func (a *API) HOSTDEFINEEND() error {
   163  	_, err := fmt.Fprintf(a, "HOST_DEFINE_END\n\n")
   164  	return err
   165  }
   166  
   167  func (a *API) HOST(guid string) error {
   168  	_, err := a.Write([]byte("HOST " + "'" + guid + "'" + "\n\n"))
   169  	return err
   170  }
   171  
   172  func (a *API) DynCfgEnable(pluginName string) error {
   173  	_, err := a.Write([]byte("DYNCFG_ENABLE '" + pluginName + "'\n\n"))
   174  	return err
   175  }
   176  
   177  func (a *API) DynCfgReset() error {
   178  	_, err := a.Write([]byte("DYNCFG_RESET\n"))
   179  	return err
   180  }
   181  
   182  func (a *API) DyncCfgRegisterModule(moduleName string) error {
   183  	_, err := fmt.Fprintf(a, "DYNCFG_REGISTER_MODULE '%s' job_array\n\n", moduleName)
   184  	return err
   185  }
   186  
   187  func (a *API) DynCfgRegisterJob(moduleName, jobName, jobType string) error {
   188  	_, err := fmt.Fprintf(a, "DYNCFG_REGISTER_JOB '%s' '%s' '%s' 0\n\n", moduleName, jobName, jobType)
   189  	return err
   190  }
   191  
   192  func (a *API) DynCfgReportJobStatus(moduleName, jobName, status, reason string) error {
   193  	_, err := fmt.Fprintf(a, "REPORT_JOB_STATUS '%s' '%s' '%s' 0 '%s'\n\n", moduleName, jobName, status, reason)
   194  	return err
   195  }
   196  
   197  func (a *API) FunctionResultSuccess(uid, contentType, payload string) error {
   198  	return a.functionResult(uid, contentType, payload, "1")
   199  }
   200  
   201  func (a *API) FunctionResultReject(uid, contentType, payload string) error {
   202  	return a.functionResult(uid, contentType, payload, "0")
   203  }
   204  
   205  func (a *API) functionResult(uid, contentType, payload, code string) error {
   206  	var buf bytes.Buffer
   207  
   208  	buf.WriteString("FUNCTION_RESULT_BEGIN " + uid + " " + code + " " + contentType + " 0\n")
   209  	if payload != "" {
   210  		buf.WriteString(payload + "\n")
   211  	}
   212  	buf.WriteString("FUNCTION_RESULT_END\n\n")
   213  
   214  	_, err := buf.WriteTo(a)
   215  	return err
   216  }