From 5c98cb26156176ffbb826cf1975ad05603cc8fd9 Mon Sep 17 00:00:00 2001
From: Adrien Waksberg <awaksberg@ingenicoprepaid.com>
Date: Thu, 27 Jun 2019 10:46:33 +0200
Subject: [PATCH 1/9] feat: add check_mysql_query_count

---
 .../check_mysql_query_count.go                | 90 +++++++++++++++++++
 1 file changed, 90 insertions(+)
 create mode 100644 check_mysql_query_count/check_mysql_query_count.go

diff --git a/check_mysql_query_count/check_mysql_query_count.go b/check_mysql_query_count/check_mysql_query_count.go
new file mode 100644
index 0000000..c3b9d83
--- /dev/null
+++ b/check_mysql_query_count/check_mysql_query_count.go
@@ -0,0 +1,90 @@
+package main
+
+import (
+	"fmt"
+	"flag"
+	"os"
+
+	"database/sql"
+	_ "github.com/go-sql-driver/mysql"
+)
+
+// Option to parse
+var (
+  HOSTNAME = flag.String("hostname", "localhost", "mysql hostname")
+  PORT     = flag.Int("port", 3306, "mysql port")
+  USERNAME = flag.String("username", "", "mysql username")
+  PASSWORD = flag.String("password", "", "mysql password")
+  DATABASE = flag.String("database", "", "mysql database")
+  QUERY    = flag.String("query", "", "mysql query")
+  WARNING  = flag.Int("warning", 0, "limit to return a warning alert")
+  CRITICAL = flag.Int("critical", 0, "limit to return a critical alert")
+)
+
+func init() {
+  flag.Parse()
+
+  if *QUERY == "" {
+    Critical("Please set query option")
+  }
+
+  if *WARNING == 0 || *CRITICAL == 0 {
+    Critical("Please set warning and critical options")
+  }
+}
+
+// Critical print a message and exit with code 2
+func Critical(msg string) {
+  fmt.Println(fmt.Sprintf("CRITICAL - %s", msg))
+  os.Exit(2)
+}
+
+// Warning print a message and exit with code 1
+func Warning(msg string) {
+  fmt.Println(fmt.Sprintf("WARNING - %s", msg))
+  os.Exit(1)
+}
+
+// Ok print a message and exit with code 0
+func Ok(msg string) {
+  fmt.Println(fmt.Sprintf("OK - %s", msg))
+  os.Exit(0)
+}
+
+// Count execute query and return the result
+func Count() (int, error) {
+  var count int
+
+  conn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", *USERNAME, *PASSWORD, *HOSTNAME, *PORT, *DATABASE)
+  db, err := sql.Open("mysql", conn)
+  if err != nil {
+    return 0, err
+  }
+  defer db.Close()
+
+  err = db.QueryRow(*QUERY).Scan(&count)
+  if err != nil {
+    return 0, err
+  }
+
+  return count, nil
+}
+
+func main() {
+  count, err := Count()
+  if err != nil {
+    Critical(fmt.Sprintf("%v", err))
+  }
+
+  msg := fmt.Sprintf("there are %d rows", count)
+  if count >= *CRITICAL {
+    Critical(msg)
+  }
+
+  if count >= *WARNING {
+    Warning(msg)
+  }
+
+  Ok(msg)
+}
+

From ab6f301467db237d76f3976fb10d61b93c04ea73 Mon Sep 17 00:00:00 2001
From: Adrien Waksberg <awaksberg@ingenicoprepaid.com>
Date: Thu, 27 Jun 2019 10:58:47 +0200
Subject: [PATCH 2/9] feat: add help option

---
 check_mysql_query_count/check_mysql_query_count.go | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/check_mysql_query_count/check_mysql_query_count.go b/check_mysql_query_count/check_mysql_query_count.go
index c3b9d83..02c5921 100644
--- a/check_mysql_query_count/check_mysql_query_count.go
+++ b/check_mysql_query_count/check_mysql_query_count.go
@@ -11,6 +11,7 @@ import (
 
 // Option to parse
 var (
+  HELP     = flag.Bool("help", false, "print the help message")
   HOSTNAME = flag.String("hostname", "localhost", "mysql hostname")
   PORT     = flag.Int("port", 3306, "mysql port")
   USERNAME = flag.String("username", "", "mysql username")
@@ -24,6 +25,11 @@ var (
 func init() {
   flag.Parse()
 
+  if *HELP {
+    flag.PrintDefaults()
+    os.Exit(3)
+  }
+
   if *QUERY == "" {
     Critical("Please set query option")
   }
@@ -87,4 +93,3 @@ func main() {
 
   Ok(msg)
 }
-

From 0cee7e7d374f37130cb6cba8b10ef2e0911966a3 Mon Sep 17 00:00:00 2001
From: Adrien Waksberg <awaksberg@ingenicoprepaid.com>
Date: Thu, 27 Jun 2019 11:34:02 +0200
Subject: [PATCH 3/9] fix: default value is -1 for critical and warning options

---
 check_mysql_query_count/check_mysql_query_count.go | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/check_mysql_query_count/check_mysql_query_count.go b/check_mysql_query_count/check_mysql_query_count.go
index 02c5921..e67f065 100644
--- a/check_mysql_query_count/check_mysql_query_count.go
+++ b/check_mysql_query_count/check_mysql_query_count.go
@@ -18,8 +18,8 @@ var (
   PASSWORD = flag.String("password", "", "mysql password")
   DATABASE = flag.String("database", "", "mysql database")
   QUERY    = flag.String("query", "", "mysql query")
-  WARNING  = flag.Int("warning", 0, "limit to return a warning alert")
-  CRITICAL = flag.Int("critical", 0, "limit to return a critical alert")
+  WARNING  = flag.Int("warning", -1, "limit to return a warning alert")
+  CRITICAL = flag.Int("critical", -1, "limit to return a critical alert")
 )
 
 func init() {
@@ -34,7 +34,7 @@ func init() {
     Critical("Please set query option")
   }
 
-  if *WARNING == 0 || *CRITICAL == 0 {
+  if *WARNING == -1 || *CRITICAL == -1 {
     Critical("Please set warning and critical options")
   }
 }

From 2a5d1eedc7577168b98a88340f0eed750ef10630 Mon Sep 17 00:00:00 2001
From: Adrien Waksberg <awaksberg@ingenicoprepaid.com>
Date: Thu, 27 Jun 2019 10:46:33 +0200
Subject: [PATCH 4/9] feat: add check_mysql_query_count

---
 .../check_mysql_query_count.go                | 95 +++++++++++++++++++
 go.mod                                        |  1 +
 2 files changed, 96 insertions(+)
 create mode 100644 check_mysql_query_count/check_mysql_query_count.go
 create mode 100644 go.mod

diff --git a/check_mysql_query_count/check_mysql_query_count.go b/check_mysql_query_count/check_mysql_query_count.go
new file mode 100644
index 0000000..e67f065
--- /dev/null
+++ b/check_mysql_query_count/check_mysql_query_count.go
@@ -0,0 +1,95 @@
+package main
+
+import (
+	"fmt"
+	"flag"
+	"os"
+
+	"database/sql"
+	_ "github.com/go-sql-driver/mysql"
+)
+
+// Option to parse
+var (
+  HELP     = flag.Bool("help", false, "print the help message")
+  HOSTNAME = flag.String("hostname", "localhost", "mysql hostname")
+  PORT     = flag.Int("port", 3306, "mysql port")
+  USERNAME = flag.String("username", "", "mysql username")
+  PASSWORD = flag.String("password", "", "mysql password")
+  DATABASE = flag.String("database", "", "mysql database")
+  QUERY    = flag.String("query", "", "mysql query")
+  WARNING  = flag.Int("warning", -1, "limit to return a warning alert")
+  CRITICAL = flag.Int("critical", -1, "limit to return a critical alert")
+)
+
+func init() {
+  flag.Parse()
+
+  if *HELP {
+    flag.PrintDefaults()
+    os.Exit(3)
+  }
+
+  if *QUERY == "" {
+    Critical("Please set query option")
+  }
+
+  if *WARNING == -1 || *CRITICAL == -1 {
+    Critical("Please set warning and critical options")
+  }
+}
+
+// Critical print a message and exit with code 2
+func Critical(msg string) {
+  fmt.Println(fmt.Sprintf("CRITICAL - %s", msg))
+  os.Exit(2)
+}
+
+// Warning print a message and exit with code 1
+func Warning(msg string) {
+  fmt.Println(fmt.Sprintf("WARNING - %s", msg))
+  os.Exit(1)
+}
+
+// Ok print a message and exit with code 0
+func Ok(msg string) {
+  fmt.Println(fmt.Sprintf("OK - %s", msg))
+  os.Exit(0)
+}
+
+// Count execute query and return the result
+func Count() (int, error) {
+  var count int
+
+  conn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s", *USERNAME, *PASSWORD, *HOSTNAME, *PORT, *DATABASE)
+  db, err := sql.Open("mysql", conn)
+  if err != nil {
+    return 0, err
+  }
+  defer db.Close()
+
+  err = db.QueryRow(*QUERY).Scan(&count)
+  if err != nil {
+    return 0, err
+  }
+
+  return count, nil
+}
+
+func main() {
+  count, err := Count()
+  if err != nil {
+    Critical(fmt.Sprintf("%v", err))
+  }
+
+  msg := fmt.Sprintf("there are %d rows", count)
+  if count >= *CRITICAL {
+    Critical(msg)
+  }
+
+  if count >= *WARNING {
+    Warning(msg)
+  }
+
+  Ok(msg)
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..46709f8
--- /dev/null
+++ b/go.mod
@@ -0,0 +1 @@
+module monitoring-plugins

From 697e5b4dceb1a3af5aa19e256d7275c9c8806259 Mon Sep 17 00:00:00 2001
From: Adrien Waksberg <git@yae.im>
Date: Sun, 3 Nov 2019 11:46:50 +0100
Subject: [PATCH 5/9] feat: add check_systemd_service

---
 check_systemd_service/main.go | 81 +++++++++++++++++++++++++++++++++++
 1 file changed, 81 insertions(+)
 create mode 100644 check_systemd_service/main.go

diff --git a/check_systemd_service/main.go b/check_systemd_service/main.go
new file mode 100644
index 0000000..0286066
--- /dev/null
+++ b/check_systemd_service/main.go
@@ -0,0 +1,81 @@
+package main
+
+import (
+	"fmt"
+	"flag"
+	"os"
+	"os/exec"
+	"strings"
+	"time"
+)
+
+// Option to parse
+var (
+  HELP     = flag.Bool("help", false, "print the help message")
+  SERVICE  = flag.String("service", "", "service name")
+  LIFETIME = flag.Int("lifetime", 60, "minimum life time in second")
+)
+
+func init() {
+  flag.Parse()
+
+  if *HELP {
+    flag.PrintDefaults()
+    os.Exit(3)
+  }
+
+  if *SERVICE == "" {
+    Critical("Please set service name")
+  }
+}
+
+// Critical print a message and exit with code 2
+func Critical(msg string) {
+  fmt.Println(fmt.Sprintf("CRITICAL - %s", msg))
+  os.Exit(2)
+}
+
+// Warning print a message and exit with code 1
+func Warning(msg string) {
+  fmt.Println(fmt.Sprintf("WARNING - %s", msg))
+  os.Exit(1)
+}
+
+// Ok print a message and exit with code 0
+func Ok(msg string) {
+  fmt.Println(fmt.Sprintf("OK - %s", msg))
+  os.Exit(0)
+}
+
+// ServiceStatus check if the service is started
+func ServiceStatus() error {
+	cmd := exec.Command("systemctl", "is-active", *SERVICE)
+	if err := cmd.Run(); err != nil {
+		return fmt.Errorf("the service is inactive")
+	}
+
+	output, err := exec.Command("systemctl", "show", *SERVICE, "-p", "ExecMainStartTimestamp", "--value").Output()
+	if err != nil {
+		return err
+	}
+
+	startDate, err  := time.Parse("Mon 2006-01-02 15:04:05 MST", strings.Trim(string(output), "\n"))
+	if err != nil {
+		return err
+	}
+
+	if startDate.Unix() > time.Now().Add(- time.Duration(*LIFETIME) * time.Second).Unix() {
+		return fmt.Errorf("the service has started for less than %d seconds", *LIFETIME)
+	}
+
+	return nil
+}
+
+func main() {
+  err := ServiceStatus()
+  if err != nil {
+    Critical(fmt.Sprintf("%v", err))
+  }
+
+  Ok("the service is active")
+}

From f4db75dd1a63baf4534a7bca1db7f286333c72fd Mon Sep 17 00:00:00 2001
From: Adrien Waksberg <git@yae.im>
Date: Sun, 3 Nov 2019 12:13:27 +0100
Subject: [PATCH 6/9] fix: rename go file

---
 check_mysql_query_count/{check_mysql_query_count.go => main.go} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename check_mysql_query_count/{check_mysql_query_count.go => main.go} (100%)

diff --git a/check_mysql_query_count/check_mysql_query_count.go b/check_mysql_query_count/main.go
similarity index 100%
rename from check_mysql_query_count/check_mysql_query_count.go
rename to check_mysql_query_count/main.go

From ab74d4f9218796cb8c790d150ea51ec4915fe2ab Mon Sep 17 00:00:00 2001
From: Adrien Waksberg <git@yae.im>
Date: Sun, 3 Nov 2019 15:46:45 +0100
Subject: [PATCH 7/9] fix: add license in source file

---
 check_mysql_query_count/main.go | 16 ++++++++++++++++
 check_systemd_service/main.go   | 16 ++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/check_mysql_query_count/main.go b/check_mysql_query_count/main.go
index e67f065..c7027fe 100644
--- a/check_mysql_query_count/main.go
+++ b/check_mysql_query_count/main.go
@@ -1,3 +1,19 @@
+/*
+  Copyright 2019 Adrien Waksberg
+  
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+  
+      https://www.apache.org/licenses/LICENSE-2.0
+  
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+*/
+
 package main
 
 import (
diff --git a/check_systemd_service/main.go b/check_systemd_service/main.go
index 0286066..94de56c 100644
--- a/check_systemd_service/main.go
+++ b/check_systemd_service/main.go
@@ -1,3 +1,19 @@
+/*
+ Copyright 2019 Adrien Waksberg
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+     https://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
 package main
 
 import (

From 0d944051a1e2317ec0252cd2d4386b499b03a618 Mon Sep 17 00:00:00 2001
From: Adrien Waksberg <git@yae.im>
Date: Sun, 3 Nov 2019 15:48:17 +0100
Subject: [PATCH 8/9] chore: update changelog

---
 CHANGELOG.md | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index f881c8d..210519c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,3 +6,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
 Which is based on [Keep A Changelog](http://keepachangelog.com/)
 
 ## Unreleased
+
+# Added
+
+- check for systemd service
+- check count for a mysql query

From a428766a3c588e79c05f399fd3afd3e7af0e474e Mon Sep 17 00:00:00 2001
From: Adrien Waksberg <git@yae.im>
Date: Sun, 3 Nov 2019 15:50:19 +0100
Subject: [PATCH 9/9] feat: add README

---
 README.md | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)
 create mode 100644 README.md

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..2d57b3b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,23 @@
+# Monitoring plugins
+
+[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://git.yaegashi.fr/nishiki/gpm/src/branch/master/LICENSE)
+
+A collection of monitoring plugins for nagios-like monitoring
+
+## License
+
+```text
+Copyright (c) 2019 Adrien Waksberg
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+```