changeset 722:815f5e2ed974

Added simple endpoint to view system logs. api/system/log/{service}/{file} allows to retrieve the raw log file content for a selected set of services (currently "apache2" and "postgresql"). The result is a JSON with two fields: "path:" contains the fully qualified path of the retrieved log file in the servers file system and "content:" provides the verbatim content of the requested log file.
author Sascha Wilde <wilde@intevation.de>
date Fri, 21 Sep 2018 18:01:39 +0200
parents ca82698349b7
children 7eed7ff3142d
files docs/server-interface.txt pkg/controllers/routes.go pkg/controllers/system.go
diffstat 3 files changed, 86 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/docs/server-interface.txt	Fri Sep 21 17:37:34 2018 +0200
+++ b/docs/server-interface.txt	Fri Sep 21 18:01:39 2018 +0200
@@ -1,26 +1,27 @@
-| Route                    | Methode  | Daten                                                 | *PUC         | JSON                                               | HTTP-Code     | Anmerkung                                      |
-|--------------------------+----------+-------------------------------------------------------+--------------+----------------------------------------------------+---------------+------------------------------------------------+
-| /api/users               | GET      | Liste an Usern                                        |              |                                                    | 200, 500      |                                                |
-| /api/users               | POST     | user, password, role, email, country, *extent         | APUC3, APUC4 |                                                    | 201, 400, 500 |                                                |
-| /api/users/{user}        | GET      |                                                       | APUC3, APUC4 | login, password, role, email, country, extent zoom | 201, 500      |                                                |
-| /api/users/{user}        | DELETE   |                                                       | APUC3        |                                                    | 204, 500      |                                                |
-| /api/users/{user}        | PUT      | user, password, role, email, country, *extent         | APUC3        | login, password, role, email, country, extent zoom | 200, 500      |                                                |
-| /api/users/passwordreset | POST     | user                                                  | GPUC3        | user                                               | 200, 500      |                                                |
-| /api/login               | GET/POST | user, password -> token im Result-JSON                | APUC1        |                                                    | 200, 500      |                                                |
-| /api/logout              | GET/POST |                                                       | APUC2        |                                                    | 200, 500      |                                                |
-| /api/renew               | GET/POST |                                                       | APUC2        |                                                    | 200, 500      |                                                |
-| /api/health/hardware     | GET      |                                                       | APUC8        |                                                    | 200, 500      | Optionale Queryparameter: limit, from, from+to |
-| /api/health/system       | GET      |                                                       | APUC8        |                                                    | 200, 500      | Optionale Queryparameter: limit, from, from+to |
-| /api/health/access       | GET      |                                                       | APUC8        |                                                    | 200, 500      | Optionale Queryparameter: limit, from, from+to |
-| /api/sendtestmail        | POST     | recipients: userids / an SAdmins, an WWAdmins         | APUC9        |                                                    | 200, 500      | !Throttle!                                     |
-| /api/management          | GET      | aktuelle Konfiguration                                | APUC10       |                                                    | 200, 500      |                                                |
-| /api/management          | PATCH    | zu ändernde Parameter                                 | APUC10       |                                                    | 200, 500      |                                                |
-| /api/templates           | GET      | Liste an Templates                                    | APUC6        |                                                    | 200, 500      |                                                |
-| /api/templates           | POST     | Daten für ein neues Template                          | APUC6        |                                                    | 201, 500      |                                                |
-| /api/templates/{id}      | GET      | Metadaten für das Template                            | APUC6        |                                                    | 200, 500      |                                                |
-| /api/template/{id}       | PATCH    | zu ändernde Parameter                                 | APUC6        |                                                    | 200, 500      |                                                |
-| /api/template/{id}       | DELETE   |                                                       | APUC6        |                                                    | 200, 500      |                                                |
-| /api/maps/print          | POST     | Metadaten für den Druck(?)                            | GPUC7        |                                                    | 200, 500      |                                                |
-| /api/search (?)          | POST     | Das zu suchende                                       | GPUC10       |                                                    | 200, 500      |                                                |
-| /api/bottlenecks         | GET      |                                                       | SPUC1        |                                                    | 200, 500      | Limit?                                         |
-| /api/fairwaydimension    | GET      | Flusskilometerangabe, Zeitpunkt(?)                    | SPUC3        |                                                    | 200, 500      | SVG?                                           |
+| Route                            | Methode  | Daten                                         | *PUC         | JSON                                               | HTTP-Code     | Anmerkung                                      |
+|----------------------------------+----------+-----------------------------------------------+--------------+----------------------------------------------------+---------------+------------------------------------------------|
+| /api/users                       | GET      | Liste an Usern                                |              |                                                    | 200, 500      |                                                |
+| /api/users                       | POST     | user, password, role, email, country, *extent | APUC3, APUC4 |                                                    | 201, 400, 500 |                                                |
+| /api/users/{user}                | GET      |                                               | APUC3, APUC4 | login, password, role, email, country, extent zoom | 201, 500      |                                                |
+| /api/users/{user}                | DELETE   |                                               | APUC3        |                                                    | 204, 500      |                                                |
+| /api/users/{user}                | PUT      | user, password, role, email, country, *extent | APUC3        | login, password, role, email, country, extent zoom | 200, 500      |                                                |
+| /api/users/passwordreset         | POST     | user                                          | GPUC3        | user                                               | 200, 500      |                                                |
+| /api/login                       | GET/POST | user, password -> token im Result-JSON        | APUC1        |                                                    | 200, 500      |                                                |
+| /api/logout                      | GET/POST |                                               | APUC2        |                                                    | 200, 500      |                                                |
+| /api/renew                       | GET/POST |                                               | APUC2        |                                                    | 200, 500      |                                                |
+| /api/system/log/{service}/{file} | GET      |                                               | APUC8        | path, content                                      | 200, 500      | Later: add limiting parameters                 |
+| /api/system/hardware             | GET      |                                               | APUC8        |                                                    | 200, 500      | Optionale Queryparameter: limit, from, from+to |
+| /api/system/system               | GET      |                                               | APUC8        |                                                    | 200, 500      | Optionale Queryparameter: limit, from, from+to |
+| /api/system/access               | GET      |                                               | APUC8        |                                                    | 200, 500      | Optionale Queryparameter: limit, from, from+to |
+| /api/sendtestmail                | POST     | recipients: userids / an SAdmins, an WWAdmins | APUC9        |                                                    | 200, 500      | !Throttle!                                     |
+| /api/management                  | GET      | aktuelle Konfiguration                        | APUC10       |                                                    | 200, 500      |                                                |
+| /api/management                  | PATCH    | zu ändernde Parameter                         | APUC10       |                                                    | 200, 500      |                                                |
+| /api/templates                   | GET      | Liste an Templates                            | APUC6        |                                                    | 200, 500      |                                                |
+| /api/templates                   | POST     | Daten für ein neues Template                  | APUC6        |                                                    | 201, 500      |                                                |
+| /api/templates/{id}              | GET      | Metadaten für das Template                    | APUC6        |                                                    | 200, 500      |                                                |
+| /api/template/{id}               | PATCH    | zu ändernde Parameter                         | APUC6        |                                                    | 200, 500      |                                                |
+| /api/template/{id}               | DELETE   |                                               | APUC6        |                                                    | 200, 500      |                                                |
+| /api/maps/print                  | POST     | Metadaten für den Druck(?)                    | GPUC7        |                                                    | 200, 500      |                                                |
+| /api/search (?)                  | POST     | Das zu suchende                               | GPUC10       |                                                    | 200, 500      |                                                |
+| /api/bottlenecks                 | GET      |                                               | SPUC1        |                                                    | 200, 500      | Limit?                                         |
+| /api/fairwaydimension            | GET      | Flusskilometerangabe, Zeitpunkt(?)            | SPUC3        |                                                    | 200, 500      | SVG?                                           |
--- a/pkg/controllers/routes.go	Fri Sep 21 17:37:34 2018 +0200
+++ b/pkg/controllers/routes.go	Fri Sep 21 18:01:39 2018 +0200
@@ -43,6 +43,12 @@
 		Handle: deleteUser,
 	})).Methods(http.MethodDelete)
 
+	// System Management
+	api.Handle("/system/log/{service}/{file}", sysAdmin(&JSONHandler{
+		Handle: showSystemLog,
+		NoConn: true,
+	})).Methods(http.MethodGet)
+
 	// Password resets.
 	api.Handle("/users/passwordreset", &JSONHandler{
 		Input:  func() interface{} { return new(models.PWResetUser) },
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/pkg/controllers/system.go	Fri Sep 21 18:01:39 2018 +0200
@@ -0,0 +1,53 @@
+package controllers
+
+import (
+	"database/sql"
+	"io/ioutil"
+	"net/http"
+	"strings"
+
+	"github.com/gorilla/mux"
+)
+
+func showSystemLog(
+	_ interface{}, req *http.Request,
+	_ *sql.Conn,
+) (jr JSONResult, err error) {
+
+	serviceName := mux.Vars(req)["service"]
+	fileName := mux.Vars(req)["file"]
+
+	// The following check is currently most likely unnecessary as I wasn't
+	// able to inject a verbatim '/' via the middleware, but better be on
+	// the safe site...
+	if strings.Contains(fileName, "/") {
+		err = JSONError{http.StatusBadRequest,
+			"error: no slashes allowed in file name"}
+		return
+	}
+
+	var path string
+
+	switch serviceName {
+	case "apache2", "postgresql":
+		path = "/var/log/" + serviceName + "/" + fileName
+	default:
+		err = JSONError{http.StatusBadRequest,
+			"error: invalid service: " + serviceName}
+		return
+	}
+
+	var txt []byte
+
+	if txt, err = ioutil.ReadFile(path); err != nil {
+		return
+	}
+
+	jr = JSONResult{
+		Result: struct {
+			Path    string `json:"path"`
+			Content string `json:"content"`
+		}{path, string(txt)},
+	}
+	return
+}