Home >Backend Development >Golang >How to pass a structure in slog logger and use its fields automatically?

How to pass a structure in slog logger and use its fields automatically?

WBOY
WBOYforward
2024-02-06 08:10:03440browse

如何在 slog 记录器中传递结构并自动使用其字段?

Question content

I am using the slog package. The problem I'm facing is that when I have most of the parameters in a struct, I have to pass too many parameters to it.

Is there a way to modify the handler to use this structure? Just like what you can do in python, send a dictionary or object as extra content and then extract the required parameters from it.

Now I have this:

g.l.Log(
    context.TODO(),
    slog.LevelInfo,
    "Sending request to server.",
    "Destination", m.route.destination,
    "Protocol", m.route.protocol,
    "Service Identifier", m.route.serID,
    "Session ID", m.GetIdentifier(),
    "Client Connection", client.RemoteAddr().String(),
    "Server Connection", destination.RemoteAddr().String(),
)

I want to do something like this:

g.l.Log(
    context.TODO(),
    slog.LevelInfo,
    "Sending request to server.",
    "message", m,
    "Client Connection", client.RemoteAddr().String(),
    "Server Connection", destination.RemoteAddr().String(),
)

what should I do?


Correct answer


I found the answer to this question.

I embedded the slog logger into my custom logger.

type Logger struct {
    *slog.Logger
}

I also wrote an export function for my struct like this:

func (m *GatewayMessage) LoggableData() *xlog.RequestData {
    return &xlog.RequestData{
        Request:             m.Request.String(),
        OriginalRequest:     m.OriginalRequest,
    }
}

func (m *GatewayMessage) PopulateGeneralLogData() []any {
    logData := m.LoggableData()
    return []any{
        "Request", logData.Request,
        "OriginalRequest", logData.OriginalRequest,
    }
}

I then write a helper function that takes this GatewayMessage as a parameter along with any number of parameters, such as the slog Logger's Log function. Here is an example of debugging functionality:

func LogDebug(l *xlog.Logger, ctx context.Context, msg string, m *GatewayMessage, args ...any) {
    var generalLogData []any = make([]any, 0)
    if m != nil {
        generalLogData = m.PopulateGeneralLogData()
    }
    args = append(args, generalLogData...)
    l.RuntimeDebug(
        ctx,
        msg,
        args...,
    )
}

I also use a receiver named RuntimeDebug to inject a parameter named Scope in all logs.

func (l *Logger) RuntimeDebug(ctx context.Context, msg string, args ...any) {
    args = append(args, "Scope", "Runtime")
    l.Logger.Log(
        ctx,
        slog.LevelDebug,
        msg,
        args...,
    )
}

The above is the detailed content of How to pass a structure in slog logger and use its fields automatically?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:stackoverflow.com. If there is any infringement, please contact admin@php.cn delete