diff --git a/fxcore/README.md b/fxcore/README.md index f1cc02b..d2b1aab 100644 --- a/fxcore/README.md +++ b/fxcore/README.md @@ -206,6 +206,7 @@ import ( var Bootstrapper = fxcore.NewBootstrapper().WithOptions( fxorm.FxOrmModule, // load the ORM module (provides *gorm.DB) fx.Provide(service.NewExampleService), // autowire your service (*gorm.DB auto injection) + fxcore.AsCoreExtraInfo("foo", "bar"), // register extra information to display on core dashboard ) ``` diff --git a/fxcore/info.go b/fxcore/info.go index 79bd041..feffb5b 100644 --- a/fxcore/info.go +++ b/fxcore/info.go @@ -5,8 +5,39 @@ import ( "github.com/ankorstore/yokai/log" "github.com/ankorstore/yokai/trace" "github.com/rs/zerolog" + "go.uber.org/fx" ) +// FxExtraInfo is the struct used by modules or apps to provide their extra info to fxcore. +type FxExtraInfo interface { + Name() string + Value() string +} + +// fxExtraInfo is the default [FxExtraInfo] implementation. +type fxExtraInfo struct { + name string + value string +} + +// NewFxExtraInfo returns a new FxExtraInfo. +func NewFxExtraInfo(name string, value string) FxExtraInfo { + return &fxExtraInfo{ + name: name, + value: value, + } +} + +// Name returns the name of the [fxExtraInfo]. +func (i *fxExtraInfo) Name() string { + return i.name +} + +// Value returns the value of the [fxExtraInfo]. +func (i *fxExtraInfo) Value() string { + return i.value +} + // FxModuleInfo is the interface to implement by modules to provide their info to fxcore. type FxModuleInfo interface { Name() string @@ -23,36 +54,50 @@ type FxCoreModuleInfo struct { LogOutput string TraceProcessor string TraceSampler string + ExtraInfos map[string]string +} + +// FxCoreModuleInfoParam allows injection of the required dependencies in [NewFxCoreModuleInfo]. +type FxCoreModuleInfoParam struct { + fx.In + Config *config.Config + ExtraInfos []FxExtraInfo `group:"core-extra-infos"` } // NewFxCoreModuleInfo returns a new [FxCoreModuleInfo]. -func NewFxCoreModuleInfo(cfg *config.Config) *FxCoreModuleInfo { +func NewFxCoreModuleInfo(p FxCoreModuleInfoParam) *FxCoreModuleInfo { logLevel, logOutput := "", "" - if cfg.IsTestEnv() { + if p.Config.IsTestEnv() { logLevel = zerolog.DebugLevel.String() logOutput = log.TestOutputWriter.String() } else { - logLevel = log.FetchLogLevel(cfg.GetString("modules.log.level")).String() - logOutput = log.FetchLogOutputWriter(cfg.GetString("modules.log.output")).String() + logLevel = log.FetchLogLevel(p.Config.GetString("modules.log.level")).String() + logOutput = log.FetchLogOutputWriter(p.Config.GetString("modules.log.output")).String() } traceProcessor := "" - traceSampler := trace.FetchSampler(cfg.GetString("modules.trace.sampler.type")).String() - if cfg.IsTestEnv() { + traceSampler := trace.FetchSampler(p.Config.GetString("modules.trace.sampler.type")).String() + if p.Config.IsTestEnv() { traceProcessor = trace.TestSpanProcessor.String() } else { - traceProcessor = trace.FetchSpanProcessor(cfg.GetString("modules.trace.processor.type")).String() + traceProcessor = trace.FetchSpanProcessor(p.Config.GetString("modules.trace.processor.type")).String() + } + + extraInfos := make(map[string]string) + for _, info := range p.ExtraInfos { + extraInfos[info.Name()] = info.Value() } return &FxCoreModuleInfo{ - AppName: cfg.AppName(), - AppEnv: cfg.AppEnv(), - AppDebug: cfg.AppDebug(), - AppVersion: cfg.AppVersion(), + AppName: p.Config.AppName(), + AppEnv: p.Config.AppEnv(), + AppDebug: p.Config.AppDebug(), + AppVersion: p.Config.AppVersion(), LogLevel: logLevel, LogOutput: logOutput, TraceProcessor: traceProcessor, TraceSampler: traceSampler, + ExtraInfos: extraInfos, } } @@ -78,5 +123,6 @@ func (i *FxCoreModuleInfo) Data() map[string]interface{} { "processor": i.TraceProcessor, "sampler": i.TraceSampler, }, + "extra": i.ExtraInfos, } } diff --git a/fxcore/info_test.go b/fxcore/info_test.go index 7de5279..eeedcd1 100644 --- a/fxcore/info_test.go +++ b/fxcore/info_test.go @@ -16,7 +16,15 @@ func TestNewFxCoreModuleInfo(t *testing.T) { ) assert.NoError(t, err) - info := fxcore.NewFxCoreModuleInfo(cfg) + info := fxcore.NewFxCoreModuleInfo( + fxcore.FxCoreModuleInfoParam{ + Config: cfg, + ExtraInfos: []fxcore.FxExtraInfo{ + fxcore.NewFxExtraInfo("foo", "bar"), + fxcore.NewFxExtraInfo("foo", "baz"), + }, + }, + ) assert.IsType(t, &fxcore.FxCoreModuleInfo{}, info) assert.Implements(t, (*fxcore.FxModuleInfo)(nil), info) @@ -38,6 +46,9 @@ func TestNewFxCoreModuleInfo(t *testing.T) { "processor": "test", "sampler": "parent-based-always-on", }, + "extra": map[string]string{ + "foo": "baz", + }, }, info.Data(), ) diff --git a/fxcore/register.go b/fxcore/register.go new file mode 100644 index 0000000..065d29e --- /dev/null +++ b/fxcore/register.go @@ -0,0 +1,16 @@ +package fxcore + +import ( + "go.uber.org/fx" +) + +// AsCoreExtraInfo registers extra information in the core. +func AsCoreExtraInfo(name string, value string) fx.Option { + return fx.Supply( + fx.Annotate( + NewFxExtraInfo(name, value), + fx.As(new(FxExtraInfo)), + fx.ResultTags(`group:"core-extra-infos"`), + ), + ) +} diff --git a/fxcore/register_test.go b/fxcore/register_test.go new file mode 100644 index 0000000..23d84e3 --- /dev/null +++ b/fxcore/register_test.go @@ -0,0 +1,17 @@ +package fxcore_test + +import ( + "fmt" + "testing" + + "github.com/ankorstore/yokai/fxcore" + "github.com/stretchr/testify/assert" +) + +func TestAsCoreExtraInfo(t *testing.T) { + t.Parallel() + + result := fxcore.AsCoreExtraInfo("foo", "bar") + + assert.Equal(t, "fx.supplyOption", fmt.Sprintf("%T", result)) +} diff --git a/fxcore/registry_test.go b/fxcore/registry_test.go index 67c52d2..80d794e 100644 --- a/fxcore/registry_test.go +++ b/fxcore/registry_test.go @@ -76,7 +76,10 @@ func prepareTestFxModuleInfoRegistry() (*fxcore.FxModuleInfoRegistry, error) { return fxcore.NewFxModuleInfoRegistry(fxcore.FxModuleInfoRegistryParam{ Infos: []interface{}{ &testModuleInfo{}, - fxcore.NewFxCoreModuleInfo(cfg), + fxcore.NewFxCoreModuleInfo(fxcore.FxCoreModuleInfoParam{ + Config: cfg, + ExtraInfos: []fxcore.FxExtraInfo{}, + }), "invalid", }, }), nil diff --git a/fxcore/templates/dashboard.html b/fxcore/templates/dashboard.html index f18120d..d68291d 100644 --- a/fxcore/templates/dashboard.html +++ b/fxcore/templates/dashboard.html @@ -209,6 +209,26 @@ + {{ if ne (len .info.ExtraInfos ) 0 }} +
+
+
+

+   Extra information +

+ + + {{ range $infoName, $infoValue := .info.ExtraInfos }} + + + + + {{ end }} + +
{{ $infoName }}{{ $infoValue }}
+
+
+ {{ end }}