log15 icon indicating copy to clipboard operation
log15 copied to clipboard

Modify context

Open chendo opened this issue 11 years ago • 8 comments
trafficstars

Could we have an ability where we can change the context of a logger? I'm marking a type's attribute on the log, but it can be changed. Rather than recreating the logger every time, I'd like the ability to change a key/value pair on the context.

chendo avatar Sep 17 '14 10:09 chendo

Would log.Lazy with a context value work for you? Or is that too clumsy?

x := 1
l := log.New("x", log.Lazy{func() int { return x }})
l.Info("test") # x=1
x = 42
l.Info("lazy evaluation") # x=42

This works because the lazy function is evaluated every time the logger is invoked. This essentially lets you change context values on the fly.

inconshreveable avatar Sep 17 '14 10:09 inconshreveable

Hmmm.. Could work, but feels a bit clumsy. The attribute doesn't change that often and it feels like the overhead could be avoided.

I'm happy to use that though, thanks!

On Wednesday, September 17, 2014, inconshreveable [email protected] wrote:

Would log.Lazy with a context value work for you? Or is that too clumsy?

x := 1 l := log.New("x", log.Lazy{func() int { return x }}) l.Info("test") # x=1 x = 42 l.Info("lazy evaluation") # x=42

This works because the lazy function is evaluated every time the logger is invoked. This essentially lets you change context values on the fly.

— Reply to this email directly or view it on GitHub https://github.com/inconshreveable/log15/issues/25#issuecomment-55873889 .

Sent from my iPhone.

chendo avatar Sep 17 '14 10:09 chendo

What is the API you wished existed for this?

inconshreveable avatar Sep 17 '14 10:09 inconshreveable

Hmm, maybe something like:

l := log.New("attr", "123") # attr=123
...
l.SetContext("attr", "456") # replaces, attr=456

Or potentially a merge:

l := log.New("attr", "123")

l = l.New("attr", "456") # overwrites, attr=456

The first one is more explicit so I'd prefer that

chendo avatar Sep 17 '14 11:09 chendo

So I gave the log.Lazy a go, and it's giving showing me a LOG15_ERROR where it should be showing up.

    c.log = Log.New("connection", id.String(), "ip", host, "port", port,
        log.Lazy{func() string {
            switch c.ConnectionType {
            case ClientConnection:
                return "client"
            case DeviceConnection:
                return "device"
            }
            return ""
        }},
        log.Lazy{func() string {
            switch c.ConnectionType {
            case ClientConnection:
                return c.clientUUID
            case DeviceConnection:
                return c.deviceUUID
            }
            return ""
        }},
    )

Also, it's kind of hackish given that the connection doesn't know what type of connection it is at that point, so ideally it wouldn't even have a device=x or a client=x until it knows.

chendo avatar Sep 18 '14 01:09 chendo

You're missing key values for these values. Instead try this (I added keys for "id", "type" and "uuid"):

c.log = Log.New("connection", "id", id.String(), "ip", host, "port", port,
        "type", log.Lazy{func() string {
            switch c.ConnectionType {
            case ClientConnection:
                return "client"
            case DeviceConnection:
                return "device"
            }
            return ""
        }},
        "uuid", log.Lazy{func() string {
            switch c.ConnectionType {
            case ClientConnection:
                return c.clientUUID
            case DeviceConnection:
                return c.deviceUUID
            }
            return ""
        }},
    )

My favorite way to do this is if you control the connection class you can define two functions on it Conn.Type() and Conn.Id() and just use those with lazy instead. Like so:

c.log = Log.New("connection", "id", id.String(), "ip", host, "port", port, "type", log.Lazy{c.Type}, "uuid", log.Lazy{c.Id})

inconshreveable avatar Sep 19 '14 04:09 inconshreveable

Ah, I was hoping to have “client=” or “device=” depending on what type it is. Does Lazy not work for keys?

On Sep 19, 2014, at 2:22 PM, inconshreveable [email protected] wrote:

You're missing key values for these values. Instead try this (I added keys for "id", "type" and "uuid"): c.log = Log.New("connection", "id", id.String(), "ip", host, "port", port, "type", log.Lazy{func() string { switch c.ConnectionType { case ClientConnection: return "client" case DeviceConnection: return "device" } return "" }}, "uuid", log.Lazy{func() string { switch c.ConnectionType { case ClientConnection: return c.clientUUID case DeviceConnection: return c.deviceUUID } return "" }}, ) My favorite way to do this is if you control the connection class you can define two functions on itConn.Type() andConn.Id() and just use those with lazy instead. Like so: c.log = Log.New("connection", "id", id.String(), "ip", host, "port", port, "type", log.Lazy{c.Type}, "uuid", log.Lazy{c.Id})

— Reply to this email directly orview it on GitHub .

chendo avatar Sep 19 '14 04:09 chendo

Correct, lazy only works for values. That’s probably something I should add to the documentation.

On Sep 18, 2014, at 9:24 PM, Jack Chen [email protected] wrote:

Ah, I was hoping to have “client=” or “device=” depending on what type it is. Does Lazy not work for keys?

On Sep 19, 2014, at 2:22 PM, inconshreveable [email protected] wrote:

You're missing key values for these values. Instead try this (I added keys for "id", "type" and "uuid"): c.log = Log.New("connection", "id", id.String(), "ip", host, "port", port, "type", log.Lazy{func() string { switch c.ConnectionType { case ClientConnection: return "client" case DeviceConnection: return "device" } return "" }}, "uuid", log.Lazy{func() string { switch c.ConnectionType { case ClientConnection: return c.clientUUID case DeviceConnection: return c.deviceUUID } return "" }}, ) My favorite way to do this is if you control the connection class you can define two functions on itConn.Type() andConn.Id() and just use those with lazy instead. Like so: c.log = Log.New("connection", "id", id.String(), "ip", host, "port", port, "type", log.Lazy{c.Type}, "uuid", log.Lazy{c.Id})

— Reply to this email directly orview it on GitHub .

— Reply to this email directly or view it on GitHub.

inconshreveable avatar Sep 19 '14 04:09 inconshreveable