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 }