~otl/wildfly

15ef74062e98be21ff14b0683ec45d122f3493b5 — Oliver Lowe 1 year, 11 months ago
initial commit
A  => LICENSE +5 -0
@@ 1,5 @@
Copyright 2020 Oliver Lowe <o@olowe.co>

Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

A  => README +7 -0
@@ 1,7 @@
wildfly provides Go libraries and utilities using Wildfly's
[management HTTP API](http://docs.wildfly.org/20/Admin_Guide.html#Management_Clients). It is not intended to be an all-encompassing library, instead providing enough
to write command line utilities.

For a reference, see the [godocs](https://godocs.io/git.sr.ht/~otl/wildfly).

For example usage of the package, see cmd/check_wildflyfree.

A  => cmd/check_wildflyfree/README +48 -0
@@ 1,48 @@

check_wildflyfree(1)      BSD General Commands Manual     check_wildflyfree(1)

NAME
     check_wildflyfree — check wildfly heap memory usage

SYNOPSIS
     check_wildflyfree [−u username] [−p password] [−h host] [−w percentage]
                       [−c percentage]

DESCRIPTION
     check_wildflyfree is a plugin for Nagios/Icinga systems which checks the
     current heap memory usage of a Wildfly server and calculates the percent‐
     age of heap free.

     The options are:

     −u username
             authenticate as username.  The default is wildfly.

     −p password
             authenticate with password.  The default is wildfly.

     −h host
             check heap memory usage at host.  The default is localhost.

     −w percentage
             exit with warning when percentage amount of memory is used.  The
             default is 50.

     −c percentage
             exit with critical when percentage amount of memory is used.  The
             default is 75.

EXIT STATUS
     check_wildflyfree exits with status 0 if the memory usage is below the
     warning threshold.  Otherwise it exits with 1 or 2 if the memory usage is
     above warning or critical respectively.  On any other error it should
     exit with status 3 (UNKNOWN).

SOURCE
     https://git.sr.ht/~otl/wildflyfree

SEE ALSO
     The example icinga2 configuration file icinga2.conf in the source distri‐
     bution.

BSD                            December 22, 2020                           BSD

A  => cmd/check_wildflyfree/check_wildflyfree.1 +54 -0
@@ 1,54 @@
.Dd $Mdocdate$
.Dt check_wildflyfree 1
.Os
.Sh NAME
.Nm check_wildflyfree
.Nd check wildfly heap memory usage
.Sh SYNOPSIS
.Nm
.Op Fl u Ar username
.Op Fl p Ar password
.Op Fl h Ar host
.Op Fl w Ar percentage
.Op Fl c Ar percentage
.Sh DESCRIPTION
.Nm
is a plugin for Nagios/Icinga systems which checks the current heap memory
usage of a Wildfly server and calculates the percentage of heap free.
.Pp
The options are:
.Bl -tag -width Ds
.It Fl u Ar username
authenticate as
.Ar username .
The default is wildfly.
.It Fl p Ar password
authenticate with
.Ar password .
The default is wildfly.
.It Fl h Ar host
check heap memory usage at
.Ar host .
The default is localhost.
.It Fl w Ar percentage
exit with warning when
.Ar percentage
amount of memory is used.
The default is 50.
.It Fl c Ar percentage
exit with critical when
.Ar percentage
amount of memory is used.
The default is 75.
.El
.Sh EXIT STATUS
check_wildflyfree exits with status 0 if the memory usage is below the
warning threshold.
Otherwise it exits with 1 or 2 if the memory usage is above warning or
critical respectively.
On any other error it should exit with status 3 (UNKNOWN).
.Sh SOURCE
https://git.sr.ht/~otl/wildflyfree
.Sh SEE ALSO
The example icinga2 configuration file icinga2.conf in the source
distribution.

A  => cmd/check_wildflyfree/check_wildflyfree.go +34 -0
@@ 1,34 @@
package main

import (
	"flag"
	"os"
	"fmt"

	"git.sr.ht/~otl/wildfly"
)

func main() {
	username := flag.String("u", "wildfly", "username")
	password := flag.String("p", "wildfly", "password")
	host := flag.String("h", "localhost", "host")
	warning := flag.Int("w", 50, "warning")
	critical := flag.Int("c", 75, "critical")
	flag.Parse()

	client := wildfly.NewClient(*host, *username, *password)
	mem, err := client.StatMemory()
	if err != nil {
		fmt.Println("fetch memory usage: ", err)
		os.Exit(3)
	}
	pctused := mem.Max / mem.Used
	fmt.Printf("%d%% of heap memory used (%d of %d bytes)", pctused, mem.Used, mem.Max)
	fmt.Printf(" | heap_used_percent=%d, heap_used_bytes=%d\n", pctused, mem.Used)

	if pctused > *critical {
		os.Exit(2)
	} else if pctused > *warning {
		os.Exit(1)
	}
}

A  => cmd/check_wildflyfree/icinga2.conf +25 -0
@@ 1,25 @@
object CheckCommand "wildflyfree" {
	command = [ PluginDir + "/check_wildflyfree" ]
	arguments = {
		"-u" = "$wildfly_username$"
		"-p" = "$wildfly_password$"
		"-h" = "$wildfly_host$"
		"-w" = "$memory_warning$"
		"-c" = "$memory_critical$"
	}
	vars.wildfly_username = "wildfly"
	vars.wildfly_password = "wildfly"
	vars.wildfly_host = "$check_address$"
	vars.memory_warning = 50
	vars.memory_critical = 75
}

apply Service "wildflyfree" {
	import "generic-service"
	check_command = name
	vars.wildfly_username = "icinga"
	vars.wildfly_password = "somethingsecret"
	vars.memory_warning = 65
	vars.memory_critical = 85
	assign where host.name == "wildfly.acme.com"
}

A  => doc.go +3 -0
@@ 1,3 @@
// Package wildfly provides a read-only client of the Wildfly Management HTTP API.
// http://docs.wildfly.org/20/Admin_Guide.html
package wildfly

A  => go.mod +5 -0
@@ 1,5 @@
module git.sr.ht/~otl/wildfly

go 1.15

require github.com/icholy/digest v0.1.7

A  => go.sum +12 -0
@@ 1,12 @@
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/icholy/digest v0.1.7 h1:GkC/nKD2Sfgac5utMyacrqTkO/c+Lmj7tJ7zAZAcS98=
github.com/icholy/digest v0.1.7/go.mod h1:x+Z+2kVp6PqoAt4ssOwZ+Sz5scJ12FmA2OLqHJf5bfk=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=

A  => wildfly.go +58 -0
@@ 1,58 @@
package wildfly

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"

	"github.com/icholy/digest"
)

// Read-only client of the Wildfly Managment HTTP API. It should be created with NewClient.
type Client struct {
	host string
	*http.Client
}

// MemUsage represents the JVM's heap memory usage in bytes.
type MemUsage struct {
	Used int
	Max  int
}

// NewClient creates a new read-only client of the Wildfly server at host authenticated using user and pass
// the Wildfly's authentication mechanism: HTTP digest authentication (yuck).
func NewClient(host, user, pass string) Client {
	return Client{
		host,
		&http.Client{
			Transport: &digest.Transport{
				Username: user,
				Password: pass,
			},
		},
	}
}

func (c *Client) StatMemory() (MemUsage, error) {
	u := url.URL{
		Scheme: "http",
		Host: c.host,
		Path: "/management/core-service/platform-mbean/type/memory",
		RawQuery: "include-runtime=true&operation=attribute&name=heap-memory-usage",
	}
	resp, err := c.Get(u.String())
	if err != nil {
		return MemUsage{}, err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return MemUsage{}, fmt.Errorf("%s: %s", resp.Status, resp.Body)
	}
	var mu MemUsage
	if err := json.NewDecoder(resp.Body).Decode(&mu); err != nil {
		return MemUsage{}, fmt.Errorf("decode response: %v", err)
	}
	return mu, nil
}