diff options
-rw-r--r-- | api/admin.go | 2 | ||||
-rw-r--r-- | api4/system.go | 17 | ||||
-rw-r--r-- | api4/system_test.go | 41 | ||||
-rw-r--r-- | app/admin.go | 21 | ||||
-rw-r--r-- | einterfaces/cluster.go | 2 | ||||
-rw-r--r-- | model/client4.go | 13 |
6 files changed, 89 insertions, 7 deletions
diff --git a/api/admin.go b/api/admin.go index 14c355701..59890c739 100644 --- a/api/admin.go +++ b/api/admin.go @@ -46,7 +46,7 @@ func InitAdmin() { } func getLogs(c *Context, w http.ResponseWriter, r *http.Request) { - lines, err := app.GetLogs() + lines, err := app.GetLogs(0, 100000) if err != nil { c.Err = err return diff --git a/api4/system.go b/api4/system.go index d33be0c66..f12d802ef 100644 --- a/api4/system.go +++ b/api4/system.go @@ -21,6 +21,8 @@ func InitSystem() { BaseRoutes.ApiRoot.Handle("/email/test", ApiSessionRequired(testEmail)).Methods("POST") BaseRoutes.ApiRoot.Handle("/database/recycle", ApiSessionRequired(databaseRecycle)).Methods("POST") BaseRoutes.ApiRoot.Handle("/caches/invalidate", ApiSessionRequired(invalidateCaches)).Methods("POST") + + BaseRoutes.ApiRoot.Handle("/logs", ApiSessionRequired(getLogs)).Methods("GET") } func getSystemPing(c *Context, w http.ResponseWriter, r *http.Request) { @@ -94,3 +96,18 @@ func invalidateCaches(c *Context, w http.ResponseWriter, r *http.Request) { w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") ReturnStatusOK(w) } + +func getLogs(c *Context, w http.ResponseWriter, r *http.Request) { + if !app.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) { + c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM) + return + } + + lines, err := app.GetLogs(c.Params.Page, c.Params.PerPage) + if err != nil { + c.Err = err + return + } + + w.Write([]byte(model.ArrayToJson(lines))) +} diff --git a/api4/system_test.go b/api4/system_test.go index 4da91f428..80b4996ca 100644 --- a/api4/system_test.go +++ b/api4/system_test.go @@ -4,6 +4,7 @@ import ( "strings" "testing" + l4g "github.com/alecthomas/log4go" "github.com/mattermost/platform/model" "github.com/mattermost/platform/utils" ) @@ -145,3 +146,43 @@ func TestInvalidateCaches(t *testing.T) { t.Fatal("should clean the cache") } } + +func TestGetLogs(t *testing.T) { + th := Setup().InitBasic().InitSystemAdmin() + defer TearDown() + Client := th.Client + + for i := 0; i < 20; i++ { + l4g.Info(i) + } + + logs, resp := th.SystemAdminClient.GetLogs(0, 10) + CheckNoError(t, resp) + + if len(logs) != 10 { + t.Log(len(logs)) + t.Fatal("wrong length") + } + + logs, resp = th.SystemAdminClient.GetLogs(1, 10) + CheckNoError(t, resp) + + if len(logs) != 10 { + t.Log(len(logs)) + t.Fatal("wrong length") + } + + logs, resp = th.SystemAdminClient.GetLogs(-1, -1) + CheckNoError(t, resp) + + if len(logs) != 0 { + t.Fatal("should not be empty") + } + + _, resp = Client.GetLogs(0, 10) + CheckForbiddenStatus(t, resp) + + Client.Logout() + _, resp = Client.GetLogs(0, 10) + CheckUnauthorizedStatus(t, resp) +} diff --git a/app/admin.go b/app/admin.go index c551da50c..509d81840 100644 --- a/app/admin.go +++ b/app/admin.go @@ -18,14 +18,14 @@ import ( "github.com/mattermost/platform/utils" ) -func GetLogs() ([]string, *model.AppError) { - lines, err := GetLogsSkipSend() +func GetLogs(page, perPage int) ([]string, *model.AppError) { + lines, err := GetLogsSkipSend(page, perPage) if err != nil { return nil, err } if einterfaces.GetClusterInterface() != nil { - clines, err := einterfaces.GetClusterInterface().GetLogs() + clines, err := einterfaces.GetClusterInterface().GetLogs(page, perPage) if err != nil { return nil, err } @@ -36,7 +36,7 @@ func GetLogs() ([]string, *model.AppError) { return lines, nil } -func GetLogsSkipSend() ([]string, *model.AppError) { +func GetLogsSkipSend(page, perPage int) ([]string, *model.AppError) { var lines []string if utils.Cfg.LogSettings.EnableFile { @@ -47,9 +47,20 @@ func GetLogsSkipSend() ([]string, *model.AppError) { defer file.Close() + offsetCount := 0 + limitCount := 0 scanner := bufio.NewScanner(file) for scanner.Scan() { - lines = append(lines, scanner.Text()) + if limitCount >= perPage { + break + } + + if offsetCount >= page*perPage { + lines = append(lines, scanner.Text()) + limitCount++ + } else { + offsetCount++ + } } } else { lines = append(lines, "") diff --git a/einterfaces/cluster.go b/einterfaces/cluster.go index b7ba55144..1c6b1e071 100644 --- a/einterfaces/cluster.go +++ b/einterfaces/cluster.go @@ -23,7 +23,7 @@ type ClusterInterface interface { InvalidateCacheForReactions(postId string) Publish(event *model.WebSocketEvent) UpdateStatus(status *model.Status) - GetLogs() ([]string, *model.AppError) + GetLogs(page, perPage int) ([]string, *model.AppError) GetClusterId() string ConfigChanged(previousConfig *model.Config, newConfig *model.Config, sendToOtherServer bool) *model.AppError InvalidateAllCaches() *model.AppError diff --git a/model/client4.go b/model/client4.go index 6e862a1db..a2878df6f 100644 --- a/model/client4.go +++ b/model/client4.go @@ -1604,3 +1604,16 @@ func (c *Client4) UploadBrandImage(data []byte) (bool, *Response) { return CheckStatusOK(rp), BuildResponse(rp) } } + +// Logs Section + +// GetLogs page of logs as a string array. +func (c *Client4) GetLogs(page, perPage int) ([]string, *Response) { + query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage) + if r, err := c.DoApiGet("/logs"+query, ""); err != nil { + return nil, &Response{StatusCode: r.StatusCode, Error: err} + } else { + defer closeBody(r) + return ArrayFromJson(r.Body), BuildResponse(r) + } +} |