After a year and a half of tossing, go-spring v1.1.1 is finally released. This is a fully refactored version, which is more in line with the development habits of the go language.

  • It is a brand new version, the naming is more in line with the go specification, the module division is more reasonable, and the core design is more concise;
  • It is a version with a major breakthrough, a breakthrough in supporting the unified log framework, and a breakthrough in supporting traffic recording and playback;
  • It’s a feature-rich version that covers everything you need for day-to-day development, so you don’t have to struggle with which dependency package to use.

1. The new version of the log module fully follows the log4j2 architecture and has super flexible adaptation capabilities.

func init() {
log.RegisterPlugin(“ExampleLayout”, log.PluginTypeLayout, (*ExampleLayout)(nil))
}

type ExampleLayout struct {
LineBreak bool `PluginAttribute:”lineBreak,default=true”`
}

func (c *ExampleLayout) ToBytes(e *log.Event) ([]byte, error) {
buf := bytes.NewBuffer(nil)
enc := log.NewFlatEncoder(buf, “||”)
prefix := fmt.Sprintf(“[%s][%s:%d][%s] “, e.Level(), e.File(), e.Level(), e.Time().Format(“2006-01-02 15:04:05.000”))
err := enc.AppendBuffer([]byte(prefix))
if err != nil {
return nil, err
}
if ctx := e.Entry().Context(); ctx != nil {
span := SpanFromContext(ctx)
if span != nil {
s := fmt.Sprintf(“trace_id=%s||span_id=%s||”, span.TraceID, span.SpanID)
err = enc.AppendBuffer([]byte(s))
if err != nil {
return nil, err
}
}
}
for _, f := range e.Fields() {
err = enc.AppendKey(f.Key)
if err != nil {
return nil, err
}
err = f.Val.Encode(enc)
if err != nil {
return nil, err
}
}
if c.LineBreak {
buf.WriteByte(‘\n’)
}
return buf.Bytes(), nil
}

func main() {

config := `













`

err := log.RefreshBuffer(config, “.xml”)
util.Panic(err).When(err != nil)

logger := log.GetLogger(“xxx”)
logger.Info(“a”, “=”, “1”)
logger.Infof(“a=1”)
logger.Infow(log.Message(“a=%d”, 1))

span := &Span{TraceID: “1111”, SpanID: “2222”}
ctx := ContextWithSpan(context.Background(), span)
logger.WithContext(ctx).Info(“a”, “=”, “1”)
logger.WithContext(ctx).Infof(“a=1”)
logger.WithContext(ctx).Infow(log.Message(“a=%d”, 1))
}

/////////////////////////// observability //////////////////// /////////

type Span struct {
TraceID string
SpanID string
}

type spanKeyType int

var spanKey spanKeyType

func SpanFromContext(ctx context.Context) *Span {
v := ctx.Value(spanKey)
if v == nil {
return nil
}
return v.(*Span)
}

func ContextWithSpan(ctx context.Context, span *Span) context.Context {
return context.WithValue(ctx, spanKey, span)
}

2. The new version of the IoC container supports Logger injection, which is very convenient for daily development and supports structured logs.

type MyController struct {
Logger *log.Logger `logger:””`
}

func (c *MyController) onInit(ctx gs.Context) error {
ctx.Go(func(ctx context.Context) {
defer func() { c.Logger.Info(“exit after waiting in ::Go”) }()

ticker := time.NewTicker(10 * time.Millisecond)
defer ticker.Stop()

for {
select {
case <-ctx.Done():
return
case <-ticker.C:
c.Logger.Info(“::Go”)
}
}
})
return nil
}

3. The new version supports not using Go-Spring’s built-in startup architecture at all, and only using the IoC container to start Web services.

package main

import (
“fmt”
“net/http”

“github.com/gin-gonic/gin”
“github.com/go-spring/spring-base/log”
“github.com/go-spring/spring-base/util”
“github.com/go-spring/spring-core/gs”
)

//—————- Controller —————————–//

type Controller struct {
HelloController
}

type HelloController struct {
Service *HelloService `autowire:””`
}

func (c *HelloController) Hello(ctx *gin.Context) {
s := c.Service.Hello(ctx.Query(“name”))
ctx.String(http.StatusOK, s)
}

//—————- Service ——————————- //

type HelloService struct {
}

func (s *HelloService) Hello(name string) string {
return “hello ” + name + “!”
}

//—————- Engine —————————————– -//

type Engine struct {
Engine *gin.Engine
Address string `value:”${http.addr:=:8080}”`
Controller *Controller `autowire:””`
Exit chan struct{} `autowire:””`
}

func (e *Engine) Init() {
e.Engine = gin.Default()
e.Engine.GET(“/hello”, e.Controller.Hello)
go func() {
err := e.Engine.Run(e.Address)
fmt.Println(err)
e.Exit <- struct{}{}
}()
}

//—————- main —————————————– –//

func main() {

config := `











`
err := log.RefreshBuffer(config, “.xml”)
util.Panic(err).When(err != nil)

exit := make(chan struct{})
c := gs.New()
c.Object(exit)
c.Object(new(Controller))
c.Object(new(HelloService))
c.Object(new(Engine)).Init((*Engine).Init)
err = c.Refresh()
util.Panic(err).When(err != nil)
<-exit
c.Close()
}

#Onestop #development #framework #GoSpring #officially #released #v111 #version #News Fast Delivery

Leave a Comment

Your email address will not be published. Required fields are marked *