feat: add metrics system, move webhook feature to dedicated module (#372)

This commit is contained in:
Julien Neuhart
2021-10-19 18:35:24 +02:00
committed by GitHub
parent b839069af1
commit d4c47cecf2
39 changed files with 3359 additions and 1309 deletions

View File

@@ -67,20 +67,20 @@ func (mod *LibreOffice) Provision(ctx *gotenberg.Context) error {
return nil
}
// Routes returns the API routes.
func (mod LibreOffice) Routes() ([]api.MultipartFormDataRoute, error) {
// Routes returns the HTTP routes.
func (mod LibreOffice) Routes() ([]api.Route, error) {
if mod.disableRoutes {
return nil, nil
}
return []api.MultipartFormDataRoute{
return []api.Route{
convertRoute(mod.unoconv, mod.engine),
}, nil
}
// Interface guards.
var (
_ gotenberg.Module = (*LibreOffice)(nil)
_ gotenberg.Provisioner = (*LibreOffice)(nil)
_ api.MultipartFormDataRouter = (*LibreOffice)(nil)
_ gotenberg.Module = (*LibreOffice)(nil)
_ gotenberg.Provisioner = (*LibreOffice)(nil)
_ api.Router = (*LibreOffice)(nil)
)

View File

@@ -20,7 +20,7 @@ type UnoconvPDFEngine struct {
}
// Descriptor returns a UnoconvPDFEngine's module descriptor.
func (engine UnoconvPDFEngine) Descriptor() gotenberg.ModuleDescriptor {
func (UnoconvPDFEngine) Descriptor() gotenberg.ModuleDescriptor {
return gotenberg.ModuleDescriptor{
ID: "unoconv-pdfengine",
New: func() gotenberg.Module { return new(UnoconvPDFEngine) },

View File

@@ -8,14 +8,19 @@ import (
"github.com/gotenberg/gotenberg/v7/pkg/gotenberg"
"github.com/gotenberg/gotenberg/v7/pkg/modules/api"
"github.com/gotenberg/gotenberg/v7/pkg/modules/libreoffice/unoconv"
"github.com/labstack/echo/v4"
)
// convertRoute returns an api.MultipartFormDataRoute which can convert
// LibreOffice documents to PDF.
func convertRoute(uno unoconv.API, engine gotenberg.PDFEngine) api.MultipartFormDataRoute {
return api.MultipartFormDataRoute{
Path: "/libreoffice/convert",
Handler: func(ctx *api.Context) error {
// convertRoute returns an api.Route which can convert LibreOffice documents
// to PDF.
func convertRoute(uno unoconv.API, engine gotenberg.PDFEngine) api.Route {
return api.Route{
Method: http.MethodPost,
Path: "/forms/libreoffice/convert",
IsMultipart: true,
Handler: func(c echo.Context) error {
ctx := c.Get("context").(*api.Context)
// Let's get the data from the form and validate them.
var (
inputPaths []string

View File

@@ -9,6 +9,7 @@ import (
"github.com/gotenberg/gotenberg/v7/pkg/gotenberg"
"github.com/gotenberg/gotenberg/v7/pkg/modules/api"
"github.com/gotenberg/gotenberg/v7/pkg/modules/libreoffice/unoconv"
"github.com/labstack/echo/v4"
"go.uber.org/zap"
)
@@ -506,7 +507,10 @@ func TestConvertHandler(t *testing.T) {
expectOutputPathsCount: 2,
},
} {
err := convertRoute(tc.api, tc.engine).Handler(tc.ctx.Context)
c := echo.New().NewContext(nil, nil)
c.Set("context", tc.ctx.Context)
err := convertRoute(tc.api, tc.engine).Handler(c)
if tc.expectErr && err == nil {
t.Errorf("test %d: expected error but got: %v", i, err)

View File

@@ -8,6 +8,7 @@ import (
"os"
"strconv"
"strings"
"sync"
"github.com/gotenberg/gotenberg/v7/pkg/gotenberg"
"go.uber.org/zap"
@@ -94,6 +95,22 @@ func (mod Unoconv) Validate() error {
return nil
}
// Metrics returns the metrics.
func (mod Unoconv) Metrics() ([]gotenberg.Metric, error) {
return []gotenberg.Metric{
{
Name: "unoconv_active_instances_count",
Description: "Current number of active LibreOffice instances.",
Read: func() float64 {
activeInstancesCountMu.RLock()
defer activeInstancesCountMu.RUnlock()
return activeInstancesCount
},
},
}, nil
}
// Unoconv returns an API for interacting with unoconv.
func (mod Unoconv) Unoconv() (API, error) {
return mod, nil
@@ -163,8 +180,16 @@ func (mod Unoconv) PDF(ctx context.Context, logger *zap.Logger, inputPath, outpu
logger.Debug(fmt.Sprintf("print to PDF with: %+v", options))
activeInstancesCountMu.Lock()
activeInstancesCount += 1
activeInstancesCountMu.Unlock()
err = cmd.Exec()
activeInstancesCountMu.Lock()
activeInstancesCount -= 1
activeInstancesCountMu.Unlock()
// Always remove the user profile directory created by LibreOffice.
// See https://github.com/gotenberg/gotenberg/issues/192.
go func() {
@@ -280,11 +305,17 @@ func (mod Unoconv) Extensions() []string {
}
}
var (
activeInstancesCount float64
activeInstancesCountMu sync.RWMutex
)
// Interface guards.
var (
_ gotenberg.Module = (*Unoconv)(nil)
_ gotenberg.Provisioner = (*Unoconv)(nil)
_ gotenberg.Validator = (*Unoconv)(nil)
_ API = (*Unoconv)(nil)
_ Provider = (*Unoconv)(nil)
_ gotenberg.Module = (*Unoconv)(nil)
_ gotenberg.Provisioner = (*Unoconv)(nil)
_ gotenberg.Validator = (*Unoconv)(nil)
_ gotenberg.MetricsProvider = (*Unoconv)(nil)
_ API = (*Unoconv)(nil)
_ Provider = (*Unoconv)(nil)
)

View File

@@ -61,6 +61,22 @@ func TestUnoconv_Validate(t *testing.T) {
}
}
func TestChromium_Metrics(t *testing.T) {
metrics, err := new(Unoconv).Metrics()
if err != nil {
t.Errorf("expected no error but got: %v", err)
}
if len(metrics) != 1 {
t.Errorf("expected %d metrics, but got %d", 1, len(metrics))
}
actual := metrics[0].Read()
if actual != 0 {
t.Errorf("expected %d unoconv instances, but got %f", 0, actual)
}
}
func TestUnoconv_Unoconv(t *testing.T) {
mod := new(Unoconv)