mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
adding PM2 processes details as response of ping endpoint if LOG_LEVEL=DEBUG
This commit is contained in:
@@ -8,8 +8,10 @@ import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/thecodingmachine/gotenberg/internal/app/xhttp/pkg/context"
|
||||
"github.com/thecodingmachine/gotenberg/internal/app/xhttp/pkg/resource"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/pm2"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/printer"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/xerror"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/xlog"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/xrand"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/xtime"
|
||||
)
|
||||
@@ -28,11 +30,24 @@ const (
|
||||
func pingHandler(c echo.Context) error {
|
||||
const op string = "xhttp.pingHandler"
|
||||
ctx := context.MustCastFromEchoContext(c)
|
||||
ctx.XLogger().DebugOp(op, "handling ping request...")
|
||||
if err := ctx.ProcessesHealthcheck(); err != nil {
|
||||
logger := ctx.XLogger()
|
||||
logger.DebugOp(op, "handling ping request...")
|
||||
resolver := func() error {
|
||||
if err := ctx.ProcessesHealthcheck(); err != nil {
|
||||
return err
|
||||
}
|
||||
if logger.Level() != xlog.DebugLevel {
|
||||
return nil
|
||||
}
|
||||
list, err := pm2.List()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ctx.JSON(http.StatusOK, list)
|
||||
}
|
||||
if err := resolver(); err != nil {
|
||||
return xerror.New(op, err)
|
||||
}
|
||||
// TODO return processes info
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
@@ -15,7 +16,26 @@ import (
|
||||
"github.com/thecodingmachine/gotenberg/test"
|
||||
)
|
||||
|
||||
// TODO test ping handler
|
||||
func TestPingHandler(t *testing.T) {
|
||||
// should return 200.
|
||||
config := conf.DefaultConfig()
|
||||
srv := New(config)
|
||||
srv = New(config)
|
||||
req := httptest.NewRequest(http.MethodGet, pingEndpoint, nil)
|
||||
test.AssertStatusCode(t, http.StatusOK, srv, req)
|
||||
// should returns a JSON as
|
||||
// LOG_LEVEL is "DEBUG".
|
||||
os.Setenv(conf.LogLevelEnvVar, "DEBUG")
|
||||
config, err := conf.FromEnv()
|
||||
assert.Nil(t, err)
|
||||
srv = New(config)
|
||||
req = httptest.NewRequest(http.MethodGet, pingEndpoint, nil)
|
||||
rec := httptest.NewRecorder()
|
||||
srv.ServeHTTP(rec, req)
|
||||
assert.Equal(t, "application/json; charset=UTF-8", rec.Header().Get("Content-type"))
|
||||
assert.Equal(t, http.StatusOK, rec.Code)
|
||||
os.Unsetenv(conf.LogLevelEnvVar)
|
||||
}
|
||||
|
||||
func TestMergeHandler(t *testing.T) {
|
||||
config := conf.DefaultConfig()
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package pm2
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os/exec"
|
||||
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/xerror"
|
||||
"github.com/thecodingmachine/gotenberg/internal/pkg/xexec"
|
||||
@@ -27,8 +29,68 @@ const (
|
||||
restartCommand pm2Command = "restart"
|
||||
stopCommand pm2Command = "stop"
|
||||
logsCommand pm2Command = "logs"
|
||||
jlistCommand pm2Command = "jlist"
|
||||
)
|
||||
|
||||
/*
|
||||
JListItem is a struct
|
||||
used for unmarshaling
|
||||
ONE item of the result
|
||||
of the command "pm2 jlist".
|
||||
*/
|
||||
type JListItem struct {
|
||||
Name string `json:"name"`
|
||||
PM2Env struct {
|
||||
Status string `json:"status"`
|
||||
} `json:"pm2_env"`
|
||||
Monit struct {
|
||||
Memory int64 `json:"memory"`
|
||||
CPU float64 `json:"cpu"`
|
||||
} `json:"monit"`
|
||||
}
|
||||
|
||||
/*
|
||||
JList is a struct
|
||||
used for unmarshaling
|
||||
the result of the command
|
||||
"pm2 jlist".
|
||||
*/
|
||||
type JList []JListItem
|
||||
|
||||
func (list JList) isOnline(p Process) bool {
|
||||
const onlineStatus string = "online"
|
||||
for _, item := range list {
|
||||
if item.Name == p.binary() {
|
||||
return item.PM2Env.Status == onlineStatus
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// List returns the
|
||||
// processes details.
|
||||
func List() (*JList, error) {
|
||||
const op = "pm2.List"
|
||||
resolver := func() (*JList, error) {
|
||||
out, err := exec.
|
||||
Command("pm2", string(jlistCommand)).
|
||||
Output()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data := &JList{}
|
||||
if err := json.Unmarshal(out, data); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
list, err := resolver()
|
||||
if err != nil {
|
||||
return nil, xerror.New(op, err)
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
||||
func start(logger xlog.Logger, process Process) error {
|
||||
const (
|
||||
op string = "pm2.start"
|
||||
|
||||
@@ -32,10 +32,36 @@ func (p unoconvProcess) Start() error {
|
||||
}
|
||||
|
||||
func (p unoconvProcess) IsViable() bool {
|
||||
// TODO find a way to check if
|
||||
// the unoconv listener
|
||||
// is correctly started?
|
||||
return true
|
||||
const op string = "pm2.unoconvProcess.IsViable"
|
||||
p.logger.DebugfOp(
|
||||
op,
|
||||
"checking '%s' viability via PM2",
|
||||
p.Fullname(),
|
||||
)
|
||||
list, err := List()
|
||||
if err != nil {
|
||||
p.logger.ErrorfOp(
|
||||
op,
|
||||
"'%s' seems not viable as retrieving the list of processes via 'pm2 jlist' returned '%v'",
|
||||
p.Fullname(),
|
||||
err,
|
||||
)
|
||||
return false
|
||||
}
|
||||
if list.isOnline(p) {
|
||||
p.logger.DebugfOp(
|
||||
op,
|
||||
"'%s' is viable as its status is 'online'",
|
||||
p.Fullname(),
|
||||
)
|
||||
return true
|
||||
}
|
||||
p.logger.DebugfOp(
|
||||
op,
|
||||
"'%s' is not viable as its status is not 'online'",
|
||||
p.Fullname(),
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
func (p unoconvProcess) Stop() error {
|
||||
|
||||
Reference in New Issue
Block a user