chore(runtime): Add logrus logging framework with structured logging
Add logrus as the primary logging framework with dependency injection pattern. All errors now use WithError() for context, and structured logging uses camelCase field names. Tag runtime service with service field for better log organization. - Add logrus dependency - Update Runtime to accept logger via dependency injection - Add WithLogger() option for logger configuration - Log errors with WithError() for context - Log async function failures with service context - Document logging practices in AGENTS.md
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
package runtime
|
||||
|
||||
import "io"
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
type RuntimeOption func(*Runtime)
|
||||
|
||||
@@ -17,3 +21,9 @@ func WithStderr(stderr io.Writer) RuntimeOption {
|
||||
r.opts.Stderr = stderr
|
||||
}
|
||||
}
|
||||
|
||||
func WithLogger(logger *logrus.Logger) RuntimeOption {
|
||||
return func(r *Runtime) {
|
||||
r.logger = logger.WithField("service", "runtime")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"github.com/evanw/esbuild/pkg/api"
|
||||
"github.com/fastschema/qjs"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"reichard.io/poiesis/internal/functions"
|
||||
_ "reichard.io/poiesis/internal/stdlib"
|
||||
@@ -18,11 +19,13 @@ type Runtime struct {
|
||||
opts qjs.Option
|
||||
funcs map[string]functions.Function
|
||||
typeDecls map[string]string
|
||||
logger *logrus.Entry
|
||||
}
|
||||
|
||||
func New(ctx context.Context, opts ...RuntimeOption) (*Runtime, error) {
|
||||
// Create Runtime
|
||||
r := &Runtime{opts: qjs.Option{Context: ctx}}
|
||||
logger := logrus.New()
|
||||
r := &Runtime{opts: qjs.Option{Context: ctx}, logger: logger.WithField("service", "runtime")}
|
||||
for _, opt := range opts {
|
||||
opt(r)
|
||||
}
|
||||
@@ -30,12 +33,14 @@ func New(ctx context.Context, opts ...RuntimeOption) (*Runtime, error) {
|
||||
// Create QuickJS Context
|
||||
rt, err := qjs.New(r.opts)
|
||||
if err != nil {
|
||||
logger.WithError(err).Error("Failed to create QuickJS context")
|
||||
return nil, err
|
||||
}
|
||||
r.ctx = rt.Context()
|
||||
|
||||
// Populate Globals
|
||||
if err := r.populateGlobals(); err != nil {
|
||||
logger.WithError(err).Error("Failed to populate globals")
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -62,6 +67,7 @@ func (r *Runtime) populateGlobals() error {
|
||||
r.ctx.SetAsyncFunc(name, func(this *qjs.This) {
|
||||
qjsVal, err := callFunc(this, fn)
|
||||
if err != nil {
|
||||
r.logger.WithError(err).Errorf("Async function %s failed", name)
|
||||
_ = this.Promise().Reject(this.Context().NewError(err))
|
||||
return
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user