create simplelog Logger interface
This commit is contained in:
parent
504eb2fa69
commit
32fbe7e4a8
4 changed files with 114 additions and 33 deletions
|
|
@ -37,6 +37,7 @@ import (
|
|||
"oss.terrastruct.com/d2/lib/pdf"
|
||||
"oss.terrastruct.com/d2/lib/png"
|
||||
"oss.terrastruct.com/d2/lib/pptx"
|
||||
"oss.terrastruct.com/d2/lib/simplelog"
|
||||
"oss.terrastruct.com/d2/lib/textmeasure"
|
||||
timelib "oss.terrastruct.com/d2/lib/time"
|
||||
"oss.terrastruct.com/d2/lib/version"
|
||||
|
|
@ -749,10 +750,11 @@ func _render(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts
|
|||
}
|
||||
|
||||
cacheImages := ms.Env.Getenv("IMG_CACHE") == "1"
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, svg, cacheImages)
|
||||
l := simplelog.FromCmdLog(ms.Log)
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, l, svg, cacheImages)
|
||||
if bundle {
|
||||
var bundleErr2 error
|
||||
svg, bundleErr2 = imgbundler.BundleRemote(ctx, svg, cacheImages)
|
||||
svg, bundleErr2 = imgbundler.BundleRemote(ctx, l, svg, cacheImages)
|
||||
bundleErr = multierr.Combine(bundleErr, bundleErr2)
|
||||
}
|
||||
if forceAppendix && !toPNG {
|
||||
|
|
@ -765,7 +767,7 @@ func _render(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts
|
|||
|
||||
if !bundle {
|
||||
var bundleErr2 error
|
||||
svg, bundleErr2 = imgbundler.BundleRemote(ctx, svg, cacheImages)
|
||||
svg, bundleErr2 = imgbundler.BundleRemote(ctx, l, svg, cacheImages)
|
||||
bundleErr = multierr.Combine(bundleErr, bundleErr2)
|
||||
}
|
||||
|
||||
|
|
@ -835,8 +837,9 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opt
|
|||
}
|
||||
|
||||
cacheImages := ms.Env.Getenv("IMG_CACHE") == "1"
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, svg, cacheImages)
|
||||
svg, bundleErr2 := imgbundler.BundleRemote(ctx, svg, cacheImages)
|
||||
l := simplelog.FromCmdLog(ms.Log)
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, l, svg, cacheImages)
|
||||
svg, bundleErr2 := imgbundler.BundleRemote(ctx, l, svg, cacheImages)
|
||||
bundleErr = multierr.Combine(bundleErr, bundleErr2)
|
||||
if bundleErr != nil {
|
||||
return svg, bundleErr
|
||||
|
|
@ -936,8 +939,9 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
|
|||
}
|
||||
|
||||
cacheImages := ms.Env.Getenv("IMG_CACHE") == "1"
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, svg, cacheImages)
|
||||
svg, bundleErr2 := imgbundler.BundleRemote(ctx, svg, cacheImages)
|
||||
l := simplelog.FromCmdLog(ms.Log)
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, l, svg, cacheImages)
|
||||
svg, bundleErr2 := imgbundler.BundleRemote(ctx, l, svg, cacheImages)
|
||||
bundleErr = multierr.Combine(bundleErr, bundleErr2)
|
||||
if bundleErr != nil {
|
||||
return nil, bundleErr
|
||||
|
|
@ -1182,8 +1186,9 @@ func renderPNGsForGIF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plug
|
|||
}
|
||||
|
||||
cacheImages := ms.Env.Getenv("IMG_CACHE") == "1"
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, svg, cacheImages)
|
||||
svg, bundleErr2 := imgbundler.BundleRemote(ctx, svg, cacheImages)
|
||||
l := simplelog.FromCmdLog(ms.Log)
|
||||
svg, bundleErr := imgbundler.BundleLocal(ctx, l, svg, cacheImages)
|
||||
svg, bundleErr2 := imgbundler.BundleRemote(ctx, l, svg, cacheImages)
|
||||
bundleErr = multierr.Combine(bundleErr, bundleErr2)
|
||||
if bundleErr != nil {
|
||||
return nil, nil, bundleErr
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import (
|
|||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"oss.terrastruct.com/d2/lib/log"
|
||||
"oss.terrastruct.com/d2/lib/simplelog"
|
||||
"oss.terrastruct.com/util-go/xdefer"
|
||||
)
|
||||
|
||||
|
|
@ -29,12 +29,12 @@ const maxImageSize int64 = 1 << 25 // 33_554_432
|
|||
|
||||
var imageRegex = regexp.MustCompile(`<image href="([^"]+)"`)
|
||||
|
||||
func BundleLocal(ctx context.Context, in []byte, cacheImages bool) ([]byte, error) {
|
||||
return bundle(ctx, in, false, cacheImages)
|
||||
func BundleLocal(ctx context.Context, l simplelog.Logger, in []byte, cacheImages bool) ([]byte, error) {
|
||||
return bundle(ctx, l, in, false, cacheImages)
|
||||
}
|
||||
|
||||
func BundleRemote(ctx context.Context, in []byte, cacheImages bool) ([]byte, error) {
|
||||
return bundle(ctx, in, true, cacheImages)
|
||||
func BundleRemote(ctx context.Context, l simplelog.Logger, in []byte, cacheImages bool) ([]byte, error) {
|
||||
return bundle(ctx, l, in, true, cacheImages)
|
||||
}
|
||||
|
||||
type repl struct {
|
||||
|
|
@ -42,7 +42,7 @@ type repl struct {
|
|||
to []byte
|
||||
}
|
||||
|
||||
func bundle(ctx context.Context, svg []byte, isRemote, cacheImages bool) (_ []byte, err error) {
|
||||
func bundle(ctx context.Context, l simplelog.Logger, svg []byte, isRemote, cacheImages bool) (_ []byte, err error) {
|
||||
if isRemote {
|
||||
defer xdefer.Errorf(&err, "failed to bundle remote images")
|
||||
} else {
|
||||
|
|
@ -54,7 +54,7 @@ func bundle(ctx context.Context, svg []byte, isRemote, cacheImages bool) (_ []by
|
|||
ctx, cancel := context.WithTimeout(ctx, time.Minute*5)
|
||||
defer cancel()
|
||||
|
||||
return runWorkers(ctx, svg, imgs, isRemote, cacheImages)
|
||||
return runWorkers(ctx, l, svg, imgs, isRemote, cacheImages)
|
||||
}
|
||||
|
||||
// filterImageElements finds all unique image elements in imgs that are
|
||||
|
|
@ -84,7 +84,7 @@ func filterImageElements(imgs [][][]byte, isRemote bool) [][][]byte {
|
|||
return imgs2
|
||||
}
|
||||
|
||||
func runWorkers(ctx context.Context, svg []byte, imgs [][][]byte, isRemote, cacheImages bool) (_ []byte, err error) {
|
||||
func runWorkers(ctx context.Context, l simplelog.Logger, svg []byte, imgs [][][]byte, isRemote, cacheImages bool) (_ []byte, err error) {
|
||||
var wg sync.WaitGroup
|
||||
replc := make(chan repl)
|
||||
|
||||
|
|
@ -111,9 +111,9 @@ func runWorkers(ctx context.Context, svg []byte, imgs [][][]byte, isRemote, cach
|
|||
<-sema
|
||||
}()
|
||||
|
||||
bundledImage, err := worker(ctx, img[1], isRemote, cacheImages)
|
||||
bundledImage, err := worker(ctx, l, img[1], isRemote, cacheImages)
|
||||
if err != nil {
|
||||
log.Error(ctx, fmt.Sprintf("failed to bundle %s: %v", img[1], err))
|
||||
l.Error(fmt.Sprintf("failed to bundle %s: %v", img[1], err))
|
||||
errhrefsMu.Lock()
|
||||
errhrefs = append(errhrefs, string(img[1]))
|
||||
errhrefsMu.Unlock()
|
||||
|
|
@ -137,7 +137,7 @@ func runWorkers(ctx context.Context, svg []byte, imgs [][][]byte, isRemote, cach
|
|||
case <-ctx.Done():
|
||||
return svg, xerrors.Errorf("failed to wait for workers: %w", ctx.Err())
|
||||
case <-t.C:
|
||||
log.Info(ctx, "fetching images...")
|
||||
l.Info("fetching images...")
|
||||
case repl, ok := <-replc:
|
||||
if !ok {
|
||||
if len(errhrefs) > 0 {
|
||||
|
|
@ -150,7 +150,7 @@ func runWorkers(ctx context.Context, svg []byte, imgs [][][]byte, isRemote, cach
|
|||
}
|
||||
}
|
||||
|
||||
func worker(ctx context.Context, href []byte, isRemote, cacheImages bool) ([]byte, error) {
|
||||
func worker(ctx context.Context, l simplelog.Logger, href []byte, isRemote, cacheImages bool) ([]byte, error) {
|
||||
if cacheImages {
|
||||
if hit, ok := imgCache.Load(string(href)); ok {
|
||||
return hit.([]byte), nil
|
||||
|
|
@ -160,10 +160,10 @@ func worker(ctx context.Context, href []byte, isRemote, cacheImages bool) ([]byt
|
|||
var mimeType string
|
||||
var err error
|
||||
if isRemote {
|
||||
log.Debug(ctx, fmt.Sprintf("fetching %s remotely", string(href)))
|
||||
l.Debug(fmt.Sprintf("fetching %s remotely", string(href)))
|
||||
buf, mimeType, err = httpGet(ctx, html.UnescapeString(string(href)))
|
||||
} else {
|
||||
log.Debug(ctx, fmt.Sprintf("reading %s from disk", string(href)))
|
||||
l.Debug(fmt.Sprintf("reading %s from disk", string(href)))
|
||||
buf, err = os.ReadFile(html.UnescapeString(string(href)))
|
||||
}
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import (
|
|||
tassert "github.com/stretchr/testify/assert"
|
||||
|
||||
"oss.terrastruct.com/d2/lib/log"
|
||||
"oss.terrastruct.com/d2/lib/simplelog"
|
||||
)
|
||||
|
||||
//go:embed test_png.png
|
||||
|
|
@ -96,7 +97,8 @@ width="328" height="587" viewBox="-100 -131 328 587"><style type="text/css">
|
|||
return respRecorder.Result()
|
||||
})
|
||||
|
||||
out, err := BundleRemote(ctx, []byte(sampleSVG), false)
|
||||
l := simplelog.FromLibLog(ctx)
|
||||
out, err := BundleRemote(ctx, l, []byte(sampleSVG), false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -120,7 +122,7 @@ width="328" height="587" viewBox="-100 -131 328 587"><style type="text/css">
|
|||
respRecorder.WriteHeader(200)
|
||||
return respRecorder.Result()
|
||||
})
|
||||
_, err = BundleRemote(ctx, []byte(sampleSVG), false)
|
||||
_, err = BundleRemote(ctx, l, []byte(sampleSVG), false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -135,7 +137,7 @@ width="328" height="587" viewBox="-100 -131 328 587"><style type="text/css">
|
|||
respRecorder.WriteHeader(200)
|
||||
return respRecorder.Result()
|
||||
})
|
||||
_, err = BundleRemote(ctx, []byte(sampleSVG), false)
|
||||
_, err = BundleRemote(ctx, l, []byte(sampleSVG), false)
|
||||
if err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
|
|
@ -147,7 +149,7 @@ width="328" height="587" viewBox="-100 -131 328 587"><style type="text/css">
|
|||
respRecorder.WriteHeader(500)
|
||||
return respRecorder.Result()
|
||||
})
|
||||
_, err = BundleRemote(ctx, []byte(sampleSVG), false)
|
||||
_, err = BundleRemote(ctx, l, []byte(sampleSVG), false)
|
||||
if err == nil {
|
||||
t.Fatal("expected error")
|
||||
}
|
||||
|
|
@ -192,7 +194,8 @@ width="328" height="587" viewBox="-100 -131 328 587"><style type="text/css">
|
|||
}]]></style></svg>
|
||||
`, svgURL, pngURL)
|
||||
|
||||
out, err := BundleLocal(ctx, []byte(sampleSVG), false)
|
||||
l := simplelog.FromLibLog(ctx)
|
||||
out, err := BundleLocal(ctx, l, []byte(sampleSVG), false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -251,7 +254,8 @@ width="328" height="587" viewBox="-100 -131 328 587"><style type="text/css">
|
|||
return respRecorder.Result()
|
||||
})
|
||||
|
||||
out, err := BundleRemote(ctx, []byte(sampleSVG), false)
|
||||
l := simplelog.FromLibLog(ctx)
|
||||
out, err := BundleRemote(ctx, l, []byte(sampleSVG), false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -305,12 +309,13 @@ width="328" height="587" viewBox="-100 -131 328 587"><style type="text/css">
|
|||
return respRecorder.Result()
|
||||
})
|
||||
|
||||
l := simplelog.FromLibLog(ctx)
|
||||
// Using a cache, imgs are not refetched on multiple runs
|
||||
_, err := BundleRemote(ctx, []byte(sampleSVG), true)
|
||||
_, err := BundleRemote(ctx, l, []byte(sampleSVG), true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = BundleRemote(ctx, []byte(sampleSVG), true)
|
||||
_, err = BundleRemote(ctx, l, []byte(sampleSVG), true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -318,11 +323,11 @@ width="328" height="587" viewBox="-100 -131 328 587"><style type="text/css">
|
|||
|
||||
// With cache disabled, it refetches
|
||||
count = 0
|
||||
_, err = BundleRemote(ctx, []byte(sampleSVG), false)
|
||||
_, err = BundleRemote(ctx, l, []byte(sampleSVG), false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = BundleRemote(ctx, []byte(sampleSVG), false)
|
||||
_, err = BundleRemote(ctx, l, []byte(sampleSVG), false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
|||
71
lib/simplelog/simplelog.go
Normal file
71
lib/simplelog/simplelog.go
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// Package simplelog contains a very simple interface for logging strings at either Debug, Info, or Error levels
|
||||
package simplelog
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"oss.terrastruct.com/d2/lib/log"
|
||||
"oss.terrastruct.com/util-go/cmdlog"
|
||||
)
|
||||
|
||||
type Logger interface {
|
||||
Debug(string)
|
||||
Info(string)
|
||||
Error(string)
|
||||
}
|
||||
|
||||
type logger struct {
|
||||
logDebug *func(string)
|
||||
logInfo *func(string)
|
||||
logError *func(string)
|
||||
}
|
||||
|
||||
func (l logger) Debug(s string) {
|
||||
if l.logDebug != nil {
|
||||
(*l.logDebug)(s)
|
||||
}
|
||||
}
|
||||
func (l logger) Info(s string) {
|
||||
if l.logInfo != nil {
|
||||
(*l.logInfo)(s)
|
||||
}
|
||||
}
|
||||
func (l logger) Error(s string) {
|
||||
if l.logError != nil {
|
||||
(*l.logError)(s)
|
||||
}
|
||||
}
|
||||
|
||||
func Make(logDebug, logInfo, logError *func(string)) Logger {
|
||||
return logger{
|
||||
logDebug: logDebug,
|
||||
logInfo: logInfo,
|
||||
logError: logError,
|
||||
}
|
||||
}
|
||||
|
||||
func FromLibLog(ctx context.Context) Logger {
|
||||
lDebug := func(s string) {
|
||||
log.Debug(ctx, s)
|
||||
}
|
||||
lInfo := func(s string) {
|
||||
log.Info(ctx, s)
|
||||
}
|
||||
lError := func(s string) {
|
||||
log.Error(ctx, s)
|
||||
}
|
||||
return Make(&lDebug, &lInfo, &lError)
|
||||
}
|
||||
|
||||
func FromCmdLog(cl *cmdlog.Logger) Logger {
|
||||
lDebug := func(s string) {
|
||||
cl.Debug.Print(s)
|
||||
}
|
||||
lInfo := func(s string) {
|
||||
cl.Info.Print(s)
|
||||
}
|
||||
lError := func(s string) {
|
||||
cl.Error.Print(s)
|
||||
}
|
||||
return Make(&lDebug, &lInfo, &lError)
|
||||
}
|
||||
Loading…
Reference in a new issue