Skip to content

log.With does not compose well with log.Levels #63

@ChrisHines

Description

@ChrisHines

Context

I would like the ability to do something like this:

var Log log.Logger

func HandleTask(taskID int) error {
    logger := log.With(Log, "task", taskID)
    logger.Info("event", "start")
    ...
    logger.Debug("event", "query", "query", query)
    if err := doQuery(query); err != nil {
        logger.Error("event", "query", "err", err)
        return err
    }
    ...
    logger.Info("event", "done")
}

The important aspect of my example is the re-use of logging context across multiple severity levels.

The problem

As it stands now, package log encourages us to implement log levels via multiple Loggers each with a different level context created by a call to log.With. Unfortunately this approach makes it cumbersome to create additional contextual loggers on top of the leveled loggers. For example:

var lvls = log.NewLevels()

func HandleTask(taskID int) error {
    dlog := log.With(lvls.Debug, "task", taskID)
    ilog := log.With(lvls.Info, "task", taskID)
    elog := log.With(lvls.Error, "task", taskID)

    ilog.Log("event", "start")
    ...
    dlog.Log("event", "query", "query", query)
    if err := doQuery(query); err != nil {
        elog.Log("event", "query", "err", err)
        return err
    }
    ...
    ilog.Log("event", "done")
}

In addition to being cumbersome, each call to log.With costs allocations.

Challenge

Can we find a good way to avoid the need for multiple calls to log.With when doing leveled logging?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions