@@ -16,15 +16,15 @@ import (
1616
1717// To store the CLI parameters
1818type PipelineConfig struct {
19- PipelineName string
20- InflightEventsWarn string
21- InflightEventsCrit string
19+ PipelineName string
20+ Warning string
21+ Critical string
2222}
2323
2424// To store the parsed CLI parameters
2525type PipelineThreshold struct {
26- inflightEventsWarn * check.Threshold
27- inflightEventsCrit * check.Threshold
26+ Warning * check.Threshold
27+ Critical * check.Threshold
2828}
2929
3030var cliPipelineConfig PipelineConfig
@@ -33,19 +33,19 @@ func parsePipeThresholds(config PipelineConfig) (PipelineThreshold, error) {
3333 // Parses the CLI parameters
3434 var t PipelineThreshold
3535
36- inflightEventsWarn , err := check .ParseThreshold (config .InflightEventsWarn )
36+ warn , err := check .ParseThreshold (config .Warning )
3737 if err != nil {
3838 return t , err
3939 }
4040
41- t .inflightEventsWarn = inflightEventsWarn
41+ t .Warning = warn
4242
43- inflightEventsCrit , err := check .ParseThreshold (config .InflightEventsCrit )
43+ crit , err := check .ParseThreshold (config .Critical )
4444 if err != nil {
4545 return t , err
4646 }
4747
48- t .inflightEventsCrit = inflightEventsCrit
48+ t .Critical = crit
4949
5050 return t , nil
5151}
@@ -109,10 +109,10 @@ var pipelineCmd = &cobra.Command{
109109 inflightEvents := pipe .Events .In - pipe .Events .Out
110110
111111 summary .WriteString ("\n \\ _" )
112- if thresholds .inflightEventsCrit .DoesViolate (float64 (inflightEvents )) {
112+ if thresholds .Critical .DoesViolate (float64 (inflightEvents )) {
113113 states = append (states , check .Critical )
114114 summary .WriteString (fmt .Sprintf ("[CRITICAL] inflight_events_%s:%d;" , name , inflightEvents ))
115- } else if thresholds .inflightEventsWarn .DoesViolate (float64 (inflightEvents )) {
115+ } else if thresholds .Warning .DoesViolate (float64 (inflightEvents )) {
116116 states = append (states , check .Warning )
117117 summary .WriteString (fmt .Sprintf ("[WARNING] inflight_events_%s:%d;" , name , inflightEvents ))
118118 } else {
@@ -131,8 +131,8 @@ var pipelineCmd = &cobra.Command{
131131 Value : pipe .Events .Out })
132132 perfList .Add (& perfdata.Perfdata {
133133 Label : fmt .Sprintf ("inflight_events_%s" , name ),
134- Warn : thresholds .inflightEventsWarn ,
135- Crit : thresholds .inflightEventsCrit ,
134+ Warn : thresholds .Warning ,
135+ Crit : thresholds .Critical ,
136136 Value : inflightEvents })
137137 perfList .Add (& perfdata.Perfdata {
138138 Label : fmt .Sprintf ("pipelines.%s.reloads.failures" , name ),
@@ -253,13 +253,128 @@ var pipelineReloadCmd = &cobra.Command{
253253 },
254254}
255255
256+ var pipelineFlowCmd = & cobra.Command {
257+ Use : "flow" ,
258+ Short : "Checks the flow metrics of the Logstash Pipelines" ,
259+ Long : `Checks the flow metrics of the Logstash Pipelines` ,
260+ Example : `
261+ $ check_logstash pipeline flow --warning 5 --critical 10
262+ OK - Flow metrics alright
263+ \_[OK] queue_backpressure_example:0.34;
264+
265+ $ check_logstash pipeline flow --pipeline example --warning 5 --critical 10
266+ CRITICAL - Flow metrics not alright
267+ \_[CRITICAL] queue_backpressure_example:11.23;` ,
268+ Run : func (cmd * cobra.Command , args []string ) {
269+ var (
270+ output string
271+ rc int
272+ thresholds PipelineThreshold
273+ pp logstash.Pipeline
274+ perfList perfdata.PerfdataList
275+ )
276+
277+ // Parse the thresholds into a central var since we need them later
278+ thresholds , err := parsePipeThresholds (cliPipelineConfig )
279+ if err != nil {
280+ check .ExitError (err )
281+ }
282+
283+ // Creating an client and connecting to the API
284+ c := cliConfig .NewClient ()
285+ // localhost:9600/_node/stats/pipelines/ will return all Pipelines
286+ // localhost:9600/_node/stats/pipelines/foo will return the foo Pipeline
287+ u , _ := url .JoinPath (c .Url , "/_node/stats/pipelines" , cliPipelineConfig .PipelineName )
288+ resp , err := c .Client .Get (u )
289+
290+ if err != nil {
291+ check .ExitError (err )
292+ }
293+
294+ if resp .StatusCode != http .StatusOK {
295+ check .ExitError (fmt .Errorf ("Could not get %s - Error: %d" , u , resp .StatusCode ))
296+ }
297+
298+ defer resp .Body .Close ()
299+ err = json .NewDecoder (resp .Body ).Decode (& pp )
300+
301+ if err != nil {
302+ check .ExitError (err )
303+ }
304+
305+ states := make ([]int , 0 , len (pp .Pipelines ))
306+
307+ // Check the flow metrics for each pipeline
308+ var summary strings.Builder
309+
310+ for name , pipe := range pp .Pipelines {
311+ summary .WriteString ("\n \\ _" )
312+ if thresholds .Critical .DoesViolate (pipe .Flow .QueueBackpressure .Current ) {
313+ states = append (states , check .Critical )
314+ summary .WriteString (fmt .Sprintf ("[CRITICAL] queue_backpressure_%s:%.2f;" , name , pipe .Flow .QueueBackpressure .Current ))
315+ } else if thresholds .Warning .DoesViolate (pipe .Flow .QueueBackpressure .Current ) {
316+ states = append (states , check .Warning )
317+ summary .WriteString (fmt .Sprintf ("[WARNING] queue_backpressure_%s:%.2f;" , name , pipe .Flow .QueueBackpressure .Current ))
318+ } else {
319+ states = append (states , check .OK )
320+ summary .WriteString (fmt .Sprintf ("[OK] queue_backpressure_%s:%.2f;" , name , pipe .Flow .QueueBackpressure .Current ))
321+ }
322+
323+ // Generate perfdata for each event
324+ perfList .Add (& perfdata.Perfdata {
325+ Label : fmt .Sprintf ("pipelines.queue_backpressure_%s" , name ),
326+ Warn : thresholds .Warning ,
327+ Crit : thresholds .Critical ,
328+ Value : pipe .Flow .QueueBackpressure .Current })
329+ perfList .Add (& perfdata.Perfdata {
330+ Label : fmt .Sprintf ("pipelines.%s.output_throughput" , name ),
331+ Value : pipe .Flow .OutputThroughput .Current })
332+ perfList .Add (& perfdata.Perfdata {
333+ Label : fmt .Sprintf ("pipelines.%s.input_throughput" , name ),
334+ Value : pipe .Flow .InputThroughput .Current })
335+ perfList .Add (& perfdata.Perfdata {
336+ Label : fmt .Sprintf ("pipelines.%s.filter_throughput" , name ),
337+ Value : pipe .Flow .FilterThroughput .Current })
338+ }
339+
340+ // Validate the various subchecks and use the worst state as return code
341+ switch result .WorstState (states ... ) {
342+ case 0 :
343+ rc = check .OK
344+ output = "Flow metrics alright"
345+ case 1 :
346+ rc = check .Warning
347+ output = "Flow metrics may not be alright"
348+ case 2 :
349+ rc = check .Critical
350+ output = "Flow metrics not alright"
351+ default :
352+ rc = check .Unknown
353+ output = "Flow metrics status unknown"
354+ }
355+
356+ check .ExitRaw (rc , output , summary .String (), "|" , perfList .String ())
357+ },
358+ }
359+
256360func init () {
257361 rootCmd .AddCommand (pipelineCmd )
258362
259363 pipelineReloadCmd .Flags ().StringVarP (& cliPipelineConfig .PipelineName , "pipeline" , "P" , "/" ,
260364 "Pipeline Name" )
261365
366+ pipelineFlowCmd .Flags ().StringVarP (& cliPipelineConfig .PipelineName , "pipeline" , "P" , "/" ,
367+ "Pipeline Name" )
368+ pipelineFlowCmd .Flags ().StringVarP (& cliPipelineConfig .Warning , "warning" , "w" , "" ,
369+ "Warning threshold for queue Backpressure" )
370+ pipelineFlowCmd .Flags ().StringVarP (& cliPipelineConfig .Critical , "critical" , "c" , "" ,
371+ "Critical threshold for queue Backpressure" )
372+
373+ _ = pipelineFlowCmd .MarkFlagRequired ("warning" )
374+ _ = pipelineFlowCmd .MarkFlagRequired ("critical" )
375+
262376 pipelineCmd .AddCommand (pipelineReloadCmd )
377+ pipelineCmd .AddCommand (pipelineFlowCmd )
263378
264379 fs := pipelineCmd .Flags ()
265380
@@ -268,9 +383,9 @@ func init() {
268383 fs .StringVarP (& cliPipelineConfig .PipelineName , "pipeline" , "P" , "/" ,
269384 "Pipeline Name" )
270385
271- fs .StringVar (& cliPipelineConfig .InflightEventsWarn , "inflight-events-warn" , "" ,
386+ fs .StringVar (& cliPipelineConfig .Warning , "inflight-events-warn" , "" ,
272387 "Warning threshold for inflight events to be a warning result. Use min:max for a range." )
273- fs .StringVar (& cliPipelineConfig .InflightEventsCrit , "inflight-events-crit" , "" ,
388+ fs .StringVar (& cliPipelineConfig .Critical , "inflight-events-crit" , "" ,
274389 "Critical threshold for inflight events to be a critical result. Use min:max for a range." )
275390
276391 _ = pipelineCmd .MarkFlagRequired ("inflight-events-warn" )
0 commit comments