rs / zerolog

Zero Allocation JSON Logger
MIT License
10.33k stars 564 forks source link

getting name of the function where a log being called #670

Closed codenoid closed 4 months ago

codenoid commented 4 months ago

Hello, I'm trying to get function name where a logger is being called, currently my code is doing like this:

func logger() zerolog.Logger {
    pc, _, _, _ := runtime.Caller(1)
    funcName := runtime.FuncForPC(pc).Name()

    // Get the function name without the package path
    funcNameOnly := filepath.Ext(funcName)[1:]

    return log.With().
        // TASK 4
        // For every request received, a new request_id must be added to the log context.
        // You may use google/uuid package to generate the request_id.
        // TASK 5
        // request_id must be printed in all logs created within the request-scope.
        Str("request_id", uuid.New().String()).
        // TASK 6
        // For each function, you must add the function name to the log context.
        // For example, if there is a function named funcA, the log generated within that
        // function must also contain func key, and funcA value as additional context for all
        // logs generated within that function.
        Str("func", funcNameOnly).
        Logger()
}

func handler(w http.ResponseWriter, r *http.Request) {
    log := logger()
    // creating a new context from the logger instance
    ctx := log.WithContext(r.Context())
    {
        // TASK 2
        // You may add as many log statements as you want,
        // but you must have at least one log statement for each log level (debug, info, error).
        // You can play around with the log level by setting the global log level to info or error
        // to see the effect.

        log.Error().Ctx(ctx).
            Caller(0).
            Err(errors.New("this is an error")).
            Msg("error")

        log.Debug().Ctx(ctx).
            Caller(0).
            Str("method", r.Method).
            Str("url", r.URL.String()).
            Str("proto", r.Proto).
            Str("remote_addr", r.RemoteAddr).
            Str("ua", r.Header.Get("User-agent")).
            Msg("Incoming HTTP Request")

        log.Info().Ctx(ctx).
            Caller(0).
            Msg("request received")
    }

    w.Write([]byte("hello"))
}

there is a built-in .Caller() method, why there is no built-in method to getting the function name? or maybe there is?

thankyou

codenoid commented 4 months ago

I would like to be assigned if owner want to implement this

rs commented 4 months ago

I don't understand your question, can you please elaborate?

codenoid commented 4 months ago

there is a built-in method in zerolog called .Caller(n) with the functionality:

Caller adds the file:line of the caller with the zerolog.CallerFieldName key. The argument skip is the number of stack frames to ascend Skip If not passed, use the global variable CallerSkipFrameCount

where it add key caller with a value of file:line to the log

=========

my question is, why there is no built-in method called "CallerFunc()" (for example) where the functionality is to add caller function name to the log

rs commented 4 months ago

You can add it by customizing CallerMarshalFunc

codenoid commented 4 months ago

but my purpose was to add the caller func name to the new key instead of inside caller's default key, but maybe, this kind of change are too small for this large user's library, thanks