mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-17 20:52: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/labstack/echo/v4"
|
||||||
"github.com/thecodingmachine/gotenberg/internal/app/xhttp/pkg/context"
|
"github.com/thecodingmachine/gotenberg/internal/app/xhttp/pkg/context"
|
||||||
"github.com/thecodingmachine/gotenberg/internal/app/xhttp/pkg/resource"
|
"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/printer"
|
||||||
"github.com/thecodingmachine/gotenberg/internal/pkg/xerror"
|
"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/xrand"
|
||||||
"github.com/thecodingmachine/gotenberg/internal/pkg/xtime"
|
"github.com/thecodingmachine/gotenberg/internal/pkg/xtime"
|
||||||
)
|
)
|
||||||
@@ -28,11 +30,24 @@ const (
|
|||||||
func pingHandler(c echo.Context) error {
|
func pingHandler(c echo.Context) error {
|
||||||
const op string = "xhttp.pingHandler"
|
const op string = "xhttp.pingHandler"
|
||||||
ctx := context.MustCastFromEchoContext(c)
|
ctx := context.MustCastFromEchoContext(c)
|
||||||
ctx.XLogger().DebugOp(op, "handling ping request...")
|
logger := ctx.XLogger()
|
||||||
if err := ctx.ProcessesHealthcheck(); err != nil {
|
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)
|
return xerror.New(op, err)
|
||||||
}
|
}
|
||||||
// TODO return processes info
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
@@ -15,7 +16,26 @@ import (
|
|||||||
"github.com/thecodingmachine/gotenberg/test"
|
"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) {
|
func TestMergeHandler(t *testing.T) {
|
||||||
config := conf.DefaultConfig()
|
config := conf.DefaultConfig()
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package pm2
|
package pm2
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
"github.com/thecodingmachine/gotenberg/internal/pkg/xerror"
|
"github.com/thecodingmachine/gotenberg/internal/pkg/xerror"
|
||||||
"github.com/thecodingmachine/gotenberg/internal/pkg/xexec"
|
"github.com/thecodingmachine/gotenberg/internal/pkg/xexec"
|
||||||
@@ -27,8 +29,68 @@ const (
|
|||||||
restartCommand pm2Command = "restart"
|
restartCommand pm2Command = "restart"
|
||||||
stopCommand pm2Command = "stop"
|
stopCommand pm2Command = "stop"
|
||||||
logsCommand pm2Command = "logs"
|
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 {
|
func start(logger xlog.Logger, process Process) error {
|
||||||
const (
|
const (
|
||||||
op string = "pm2.start"
|
op string = "pm2.start"
|
||||||
|
|||||||
@@ -32,10 +32,36 @@ func (p unoconvProcess) Start() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p unoconvProcess) IsViable() bool {
|
func (p unoconvProcess) IsViable() bool {
|
||||||
// TODO find a way to check if
|
const op string = "pm2.unoconvProcess.IsViable"
|
||||||
// the unoconv listener
|
p.logger.DebugfOp(
|
||||||
// is correctly started?
|
op,
|
||||||
return true
|
"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 {
|
func (p unoconvProcess) Stop() error {
|
||||||
|
|||||||
Reference in New Issue
Block a user