FAQ
I see a lot of hate directed at the stdlib's log package, and of course,
there are a medley of third party logging packages. What are people's
problems with the standard log package? I've seen accusations that it
doesn't have leveled logging, which seems like an exercise in laziness,
because that's easy to write:

package logimport (
     "io/ioutil"
     "log"
     "os"
)
var (
     Trace = log.New(ioutil.Discard, "TRACE ", log.LstdFlags)
     Debug = log.New(os.Stdout, "DEBUG ", log.LstdFlags)
     // etc
)

With the above trivial package, you can now do log.Debug.Printf("foo!") just
like any of the third party loggers.

Some loggers are structured loggers, which again seems like not a big deal,
you can pass a map[string]interface{} into log.Printf and it'll print out
the map in a fairly easily parse-able way...

The only thing I can think of is that the time formatting is kinda ugly. I
guess the other feature is being able to change levels of logs for
individual packages, though honestly, in my ~10 years of working on
projects that use such a feature, I think I've used it all of once or twice.

What am I missing?

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Shawn Milochik at Nov 5, 2015 at 3:55 am
    I like it as-is, because it's simple to use. Much simpler than the logging
    package in Python, for example. Remember that the complainers are the ones
    who speak up. Those of us who like it don't bother to shout about it
    because otherwise we'd never shut up about "the good parts" (which is most
    of the language).

    Some people may have legitimate needs for something more complicated, and
    they're free to build it. The Go core developers never set out to provide
    everything -- not even all the stuff they *knew* we (and they) would need.
    They set out to make just enough that we could build the rest ourselves.

    If any package in the standard library isn't hefty enough for someone,
    they're free (and encouraged) to go and build or adapt their own. That
    doesn't mean that there was ever anything wrong with the standard library
    package, though. I think when people criticize something just because it
    isn't built for their use-case, they don't quite "get it." Generally I just
    keep quiet and let it pass. But, since you asked...

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Axel Wagner at Nov 5, 2015 at 7:38 am
    Hi,

    I am mostly indifferent towards the log package, but just as one note:

    Nate Finch <nate.finch@gmail.com> writes:
    Trace = log.New(ioutil.Discard, "TRACE ", log.LstdFlags)
    This may *seem* like a good idea, but it still means, that the log
    package has to do all the formatting (just to not use it). If log.Logger
    had been an interface, you could replace this with a Logger that truly
    has NOPs.
    With the above trivial package, you can now do log.Debug.Printf("foo!") just
    like any of the third party loggers.
    But, how is this different from a "third party logger"? It's a trivial
    third party logger, but it's still a package that I have to write or
    import to wrap the stdlib package. It's functionally equivalent.
    I guess the other feature is being able to change levels of logs for
    individual packages, though honestly, in my ~10 years of working on
    projects that use such a feature, I think I've used it all of once or
    twice.
    I believe it would be usefull if this existed (e.g. if every package
    would expose, as a convention or some way of technically requiring it) a
    Debug, Trace, Error… *log.Logger that you could set. I get mightily
    annoyed if third-party packages spam the stderr of my interactive
    program (because that's just bad user experience), but at the same time
    I often encounter errors that I'd like to debug where tracing would be
    very helpfull. xgb is an example of a program that used to use the
    log-package without exposing a knob.

    Another usefull thing (though that's kind of hart to do from the
    language perspective) would be dynamically scoped logging. I would like,
    during tests, to really crank up the verbosity of all packages, but have
    them log to the (*testing.T).Log functions, so that I only see it, if
    something fails. At the same time, this would need to be dynamically
    scoped, so it can't be done via global variables, because that would
    prevent parallel tests which would slow down tests considerably. There
    are ways to cheat your way out of it, though.


    Overall: What is the problem with third party loggers? Why not use a
    package that gives you more power than the stdlib, that's what packages
    are for, after all :)

    Best,

    Axel

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dave Cheney at Nov 5, 2015 at 7:51 am

    Overall: What is the problem with third party loggers? Why not use a
    package that gives you more power than the stdlib, that's what packages
    are for, after all :)
    IMO the problem with third party loggers is, well, their from a third party.

    Logging does not compose, at least not at the level of sophistication that
    the Go package ecosystem is at right now. And I'm not sure anyone would
    argue java's commons.logging "meta framework" was the thing they had in
    mind when they said sophistication.

    Different projects and packages use different logging packages, so you end
    up having to configure multiple loggers via multiple methods. I think this
    more fundamental than saying log.Logger is not an interface.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Axel Wagner at Nov 5, 2015 at 7:58 am

    Dave Cheney writes:
    Different projects and packages use different logging packages, so you end
    up having to configure multiple loggers via multiple methods. I think this
    more fundamental than saying log.Logger is not an interface.
    I agree that that's problem. It's a problem that can only solved by
    one-logging-package-to-rule-them-all™, though, at least if we agree
    *that* the stdlib log package is deficient. And the more I think about
    it, the more I think it is.

    A thing I forgot to mention btw, is: The log package exposes both a type
    *log.Logger and a set of functions that use a default. But this default
    is not exposed, so I as main can not even change how everyone is logging
    (because, of course, everyone is just using the functions instead of
    exposing their own logger).

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • James Bardin at Nov 5, 2015 at 1:51 pm

    On Thursday, November 5, 2015 at 2:58:46 AM UTC-5, Axel Wagner wrote:

    A thing I forgot to mention btw, is: The log package exposes both a type
    *log.Logger and a set of functions that use a default. But this default
    is not exposed, so I as main can not even change how everyone is logging
    (because, of course, everyone is just using the functions instead of
    exposing their own logger).
    You can SetOutput, SetFlags, and SetPrefix at the package level.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Axel Wagner at Nov 5, 2015 at 7:08 pm

    James Bardin writes:
    You can SetOutput, SetFlags, and SetPrefix at the package level.
    But *I* want to SetOutput, SetFlags and SetPrefix. In main. Every main
    has different requirements. For example, I don't mind a daemon spamming
    (on the contrary), it's just going to the log-aggregator for later
    consumption. My interactive binaries shouldn't output anything at all,
    unless something goes wrong.

    It's not a decision the package author can make, it's a decision the
    main-author must make. And unless a package exports a *log.Logger that
    it uses (which no one does, that's my point), you can't.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jakob Borg at Nov 5, 2015 at 7:54 pm

    On 5 nov. 2015, at 20:08, 'Axel Wagner' via golang-nuts wrote:

    James Bardin <j.bardin@gmail.com> writes:
    You can SetOutput, SetFlags, and SetPrefix at the package level.
    But *I* want to SetOutput, SetFlags and SetPrefix. In main. Every main
    has different requirements.
    What James probably means is that you can call log.SetOutput and so on from your main to affect the default logger.

    However I'd be suspicious in general about a reusable non-main package doing any kind of logging. In my opinion it should communicate by returning an error.

    (A program consisting of several internal packages is different of course.)

    //jb

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Axel Wagner at Nov 5, 2015 at 8:23 pm

    Jakob Borg writes:
    What James probably means is that you can call log.SetOutput and so on from your main to affect the default logger.

    However I'd be suspicious in general about a reusable non-main package
    doing any kind of logging. In my opinion it should communicate by
    returning an error.
    In a perfect world without bugs in third-party packages that may be
    defensible (I would still disagree, to be honest). But we don't live in
    a perfect world, packages have bugs and I need to debug them and
    unterstand what they are doing. An error value can never gives you the
    granularity that a verbose debug log can give you.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dave Cheney at Nov 5, 2015 at 10:20 pm
    I don't believe this is true.

    You can embed line numbers in errors, create a chain of errors with causes,
    and embed stack traces into errors ?

    Have you seen Roger Peppe's errgo package, or juju/errors package which do
    this (albeit with slightly different philosophies) ?
    On Fri, 6 Nov 2015, 07:23 Axel Wagner wrote:

    Jakob Borg <jakob@nym.se> writes:
    What James probably means is that you can call log.SetOutput and so on
    from your main to affect the default logger.
    However I'd be suspicious in general about a reusable non-main package
    doing any kind of logging. In my opinion it should communicate by
    returning an error.
    In a perfect world without bugs in third-party packages that may be
    defensible (I would still disagree, to be honest). But we don't live in
    a perfect world, packages have bugs and I need to debug them and
    unterstand what they are doing. An error value can never gives you the
    granularity that a verbose debug log can give you.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Axel Wagner at Nov 6, 2015 at 12:53 am

    Dave Cheney writes:
    I don't believe this is true.
    I concede that.

    But you are still taking away the info log-level from non-main packages
    (because returning a non-nil error is considered an error condition, so
    I can't log things that aren't errors). It also seems like a strange
    replacement to logging to me: You are trying to work around the lack of
    good, per-package logging facilities in the stdlib by abusing errors to
    in-band signal the logs. Because what's the difference between returning
    an ErrorWithLoggingInfo and just log to a custom logger, that main can
    choose to replace with a nop-logger if it's not required (or the other
    way around)? From the outside, what happens is, that you get the log
    printed to stderr (or not). And the code for both (from main) will look
    mostly the same too (in regards to activating/deactivating/redirecting/whatever
    the logs).
    You can embed line numbers in errors, create a chain of errors with causes,
    and embed stack traces into errors ?

    Have you seen Roger Peppe's errgo package, or juju/errors package which do
    this (albeit with slightly different philosophies) ?
    On Fri, 6 Nov 2015, 07:23 Axel Wagner wrote:

    Jakob Borg <jakob@nym.se> writes:
    What James probably means is that you can call log.SetOutput and so on
    from your main to affect the default logger.
    However I'd be suspicious in general about a reusable non-main package
    doing any kind of logging. In my opinion it should communicate by
    returning an error.
    In a perfect world without bugs in third-party packages that may be
    defensible (I would still disagree, to be honest). But we don't live in
    a perfect world, packages have bugs and I need to debug them and
    unterstand what they are doing. An error value can never gives you the
    granularity that a verbose debug log can give you.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Dave Cheney at Nov 6, 2015 at 1:02 am
    I'm totally with you that given the two positions of

    1. nobody gets to use any logging package in a library because you
    have applications constructed of n logging libraries operating
    independently.
    2. everyone uses the built in log package.

    Neither is acceptable.

    However, I want to counter with the question of what purpose does it
    serve to log an error inside a package? For example

    err := something()
    if err != nil {
          log.Printf("error: something failed: %v", err)
          // what do we do here ?
    }

    So, an error has occurred, the function cannot continue, but we must
    return some value to the caller. What value should we return ? It
    cannot be nil, because that would indicate success, tf. we must return
    an error value ... but we just logged the error value, will the caller
    also log it, and their caller, and theirs ?

    In this situation I do not see the value in the library logging the
    error, instead it must instead pass it up to the caller, potentially
    wrapped in some additional information in the way the juju/errors
    package does.

    Thanks

    Dave

    On Fri, Nov 6, 2015 at 11:53 AM, Axel Wagner
    wrote:
    Dave Cheney <dave@cheney.net> writes:
    I don't believe this is true.
    I concede that.

    But you are still taking away the info log-level from non-main packages
    (because returning a non-nil error is considered an error condition, so
    I can't log things that aren't errors). It also seems like a strange
    replacement to logging to me: You are trying to work around the lack of
    good, per-package logging facilities in the stdlib by abusing errors to
    in-band signal the logs. Because what's the difference between returning
    an ErrorWithLoggingInfo and just log to a custom logger, that main can
    choose to replace with a nop-logger if it's not required (or the other
    way around)? From the outside, what happens is, that you get the log
    printed to stderr (or not). And the code for both (from main) will look
    mostly the same too (in regards to activating/deactivating/redirecting/whatever
    the logs).
    You can embed line numbers in errors, create a chain of errors with causes,
    and embed stack traces into errors ?

    Have you seen Roger Peppe's errgo package, or juju/errors package which do
    this (albeit with slightly different philosophies) ?
    On Fri, 6 Nov 2015, 07:23 Axel Wagner wrote:

    Jakob Borg <jakob@nym.se> writes:
    What James probably means is that you can call log.SetOutput and so on
    from your main to affect the default logger.
    However I'd be suspicious in general about a reusable non-main package
    doing any kind of logging. In my opinion it should communicate by
    returning an error.
    In a perfect world without bugs in third-party packages that may be
    defensible (I would still disagree, to be honest). But we don't live in
    a perfect world, packages have bugs and I need to debug them and
    unterstand what they are doing. An error value can never gives you the
    granularity that a verbose debug log can give you.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Axel Wagner at Nov 6, 2015 at 7:27 am

    Dave Cheney writes:
    In this situation I do not see the value in the library logging the
    error, instead it must instead pass it up to the caller, potentially
    wrapped in some additional information in the way the juju/errors
    package does.
    I am with you on that :) But libraries might not only log errors. They
    might also want to log debug or info. And debug in particular is very
    useful imho. So something should be done to make logging possible. And I
    would be fine (though it still wouldn't be perfect, but it's something I
    could work with) if we made it best practice to have

    var (
         Debug = log.NewLogger(ioutil.Discard, …)
         Info = log.NewLogger(os.Stdout, …)
    )

    in every package (or whatever logging levels we find to be the "correct"
    ones) so that you, as an author of main, get package-level granularity
    of how logging should happen. It still wouldn't be perfect, but
    package-granularity logging control is the minimum I would expect for
    decent logging and *at the very least* the Debug level is important,
    imho. If I would want to improve on that, I would then have as
    additional steps

    a) Create a canonical interface (which *could* be provided by the
    stdlib, but might also be provided by a canonical third-party package)
    that will be used instead of *log.Logger
    b) Provide a magical implementation of that interface for tests that
    figures out which testing.T to write to (e.g. by scanning the stack) and
    use that.

    If I had all of that, I would be completely happy with logging in go. b
    is completely optional, because you wouldn't need cooperation from the
    ecosystem for it. But package-level logging is the bare minimum.

    Anyway, I think I'm out of the debate :) It's not *that* important to
    me, just wanted to give my thoughts :)

    Best,

    Axel

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Peter Mogensen at Nov 6, 2015 at 7:50 am

    On 2015-11-06 02:02, Dave Cheney wrote:
    However, I want to counter with the question of what purpose does it
    serve to log an error inside a package?
    Probably none... however it does make sense to enable lower level (INFO,
    DEBUG) messages from a library. - especially if log levels can be
    dynamically tuned at runtime.

    /Peter

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Roger peppe at Nov 6, 2015 at 8:06 am
    My main problem with the log package is that SetOutput is too low
    level - you can't plug the standard logging into some other logging
    system without parsing the log messages written to the Writer, which
    feels very fragile.
    On 6 November 2015 at 07:50, Peter Mogensen wrote:

    On 2015-11-06 02:02, Dave Cheney wrote:

    However, I want to counter with the question of what purpose does it
    serve to log an error inside a package?

    Probably none... however it does make sense to enable lower level (INFO,
    DEBUG) messages from a library. - especially if log levels can be
    dynamically tuned at runtime.

    /Peter


    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Peter Mogensen at Nov 6, 2015 at 9:08 am

    On 2015-11-06 09:06, roger peppe wrote:
    My main problem with the log package is that SetOutput is too low
    level - you can't plug the standard logging into some other logging
    system without parsing the log messages written to the Writer, which
    feels very fragile.
    Yes...
    I guess my main problem is that it discourages debug-level logging since
    you only have the Print*() functions.
    You tend to only log rare error-states to avoid flooding logs.

    We've actually stopped using the std lib logger and written our own.

    /Peter
    On 6 November 2015 at 07:50, Peter Mogensen wrote:

    On 2015-11-06 02:02, Dave Cheney wrote:

    However, I want to counter with the question of what purpose does it
    serve to log an error inside a package?

    Probably none... however it does make sense to enable lower level (INFO,
    DEBUG) messages from a library. - especially if log levels can be
    dynamically tuned at runtime.

    /Peter


    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Peter Mogensen at Nov 25, 2015 at 12:21 pm

    On 2015-11-06 10:08, Peter Mogensen wrote:
    We've actually stopped using the std lib logger and written our own.
    ... We decided to publish it:

    https://github.com/One-com/gonelog

    Now ... I'm aware that there's already way too many log libraries for Go
    around. (as the author of log15 nicely points out).

    The main reason for writing this library is not the NIH syndrome, but
    the wish to have a library which would be source code compatible with
    code written for the stdlib log package. - to allow smooth transition
    paths for code.

    I felt that goal would run counter to the design of every other log
    library out there.

    Also ... once the decision to write a new library was taken there was a
    lot of feature request which feasibility would be nice to test out.
    Those were:

    * Leveled logging with syslog levels.
    * Structured key/value logging
    * Hierarchical contextable logging to have k/v data in context logged
    automatically.
    * Low resource usage to allow more (debug) log-statements even if they
    don't result in output.
    * Light syntax to encourage logging on INFO/DEBUG level. (and low cost
    of doing so)
    * Explore compatibility with http://golang.org/x/net/context to make the
    context object a Logger.
    * Flexibility in how log events are output.
    * A fast simple lightweight default in systemd newstyle daemon only
    outputting <level>message to standard output.


    Regard the result as brainstorm of a lot of different features which
    usefulness are not really decided - but which just happens to compile,
    run and work. There's still rough edges - especially regarding formatters.

    The code has went through some cleanup and refactoring in order to
    publish, and it'll will probably go through more in response to
    comments, so the original test was dropped in refactoring.

    It does pass the stdlib test though - and seems to log a lot faster when
    just doing the most minimal logging.

    I would very much like to hear your comments.

    regards,
    Peter Mogensen

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Hariharan Srinath at Nov 6, 2015 at 12:03 pm
    I've run into similar issues in the past and i'd like to share a proposal
    to make the current Go Logging package much more extensible in a fully
    backwards compatible by allowing Logger.Output() to write logs using a
    custom logging implementation.

    The proposal is here: https://github.com/srinathh/log

    The implementation is a minor modification to log package to define a
    function type called OutputFn with the same signature as the current
    Logger.Ouptut(). The current implementation of Output is moved into a
    function called Logger.DefaultOutputFn(). We introduce a mutex protected
    variable Logger.outputfn in the Logger which points to the default
    implementation but can be swapped for any other implementation by calling
    Logger.SetOutputFn(). For the standard logger, we introduce
    log.SetOutputFn() and log.SetDefOutputFn() to set and reset custom loggers.

    The example in customlogger_test.go shows how we can use this approach to
    swap a logger that outputs logs in a tab separated variable file format but
    this approach can be easily used to plugin the Go logging system into any
    other system without text parsing etc.

    Regards
    Srinath
    On Friday, November 6, 2015 at 1:36:38 PM UTC+5:30, rog wrote:

    My main problem with the log package is that SetOutput is too low
    level - you can't plug the standard logging into some other logging
    system without parsing the log messages written to the Writer, which
    feels very fragile.

    On 6 November 2015 at 07:50, Peter Mogensen <a...@one.com <javascript:>>
    wrote:
    On 2015-11-06 02:02, Dave Cheney wrote:

    However, I want to counter with the question of what purpose does it
    serve to log an error inside a package?

    Probably none... however it does make sense to enable lower level (INFO,
    DEBUG) messages from a library. - especially if log levels can be
    dynamically tuned at runtime.

    /Peter


    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Giovanni Bajo at Nov 11, 2015 at 7:47 pm
    I feel like the problem is the opposite; I would like all third-party
    loggers to go through the standard library as final output (or middle
    stage...) to have a central convenient way for:

      * Turning on/off logging for each library
      * Setting logging level for each library

    This way, people could use logging in all libraries, and they might have be
    turned off by default; then, in my application, I could do something like
    log.Enable("github.com/spf13/cobra", log.DEBUG) when I need it, or
    something like that.

    This would bring us in the same heaven of net/http, where third-party web
    frameworks and middlewares can evolve and experiment, but all of them
    piggyback on the same basic structure so they're fully composable.

    Giovanni

    On Friday, November 6, 2015 at 9:06:38 AM UTC+1, rog wrote:

    My main problem with the log package is that SetOutput is too low
    level - you can't plug the standard logging into some other logging
    system without parsing the log messages written to the Writer, which
    feels very fragile.

    On 6 November 2015 at 07:50, Peter Mogensen <a...@one.com <javascript:>>
    wrote:
    On 2015-11-06 02:02, Dave Cheney wrote:

    However, I want to counter with the question of what purpose does it
    serve to log an error inside a package?

    Probably none... however it does make sense to enable lower level (INFO,
    DEBUG) messages from a library. - especially if log levels can be
    dynamically tuned at runtime.

    /Peter


    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts...@googlegroups.com <javascript:>.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Peter Mogensen at Nov 11, 2015 at 8:06 pm

    On 2015-11-11 20:47, Giovanni Bajo wrote:
    I feel like the problem is the opposite; I would like all third-party
    loggers to go through the standard library as final output
    That just have lousy performance. - and sacrifices a lot of features.

    I wrote a custom log library (with heavy inspiration from a lot of
    others) and tried every possible way to allow that. But it's simply not
    possible without taking the Logger Mutex way to many times.

    /Peter

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Nate Finch at Nov 6, 2015 at 4:12 am
    I think the confusion is between packages internal to your application, and
    reusable packages which are intended for general consumption including by
    third parties.

    Packages that you never intend for anyone outside your application to use
    may log all they want... they're aware of the rules of the application and
    can follow them.

    A reusable package (i.e. something for use with multiple applications, some
    of which may belong to third parties) should never ever log. Imagine if
    encoding/json decided to start logging failed decodes rather than just
    returning an error...

    In these cases, the error is absolutely the right place to return
    information. And yes, it may take some thought for some of the more
    complicated packages out there.... but it's still the only acceptable way
    to communicate.
    On Thursday, November 5, 2015 at 7:54:13 PM UTC-5, Axel Wagner wrote:

    Dave Cheney <da...@cheney.net <javascript:>> writes:
    I don't believe this is true.
    I concede that.

    But you are still taking away the info log-level from non-main packages
    (because returning a non-nil error is considered an error condition, so
    I can't log things that aren't errors). It also seems like a strange
    replacement to logging to me: You are trying to work around the lack of
    good, per-package logging facilities in the stdlib by abusing errors to
    in-band signal the logs. Because what's the difference between returning
    an ErrorWithLoggingInfo and just log to a custom logger, that main can
    choose to replace with a nop-logger if it's not required (or the other
    way around)? From the outside, what happens is, that you get the log
    printed to stderr (or not). And the code for both (from main) will look
    mostly the same too (in regards to
    activating/deactivating/redirecting/whatever
    the logs).
    You can embed line numbers in errors, create a chain of errors with causes,
    and embed stack traces into errors ?

    Have you seen Roger Peppe's errgo package, or juju/errors package which do
    this (albeit with slightly different philosophies) ?

    On Fri, 6 Nov 2015, 07:23 Axel Wagner <axel.wa...@googlemail.com
    <javascript:>> wrote:
    Jakob Borg <ja...@nym.se <javascript:>> writes:
    What James probably means is that you can call log.SetOutput and so
    on
    from your main to affect the default logger.
    However I'd be suspicious in general about a reusable non-main
    package
    doing any kind of logging. In my opinion it should communicate by
    returning an error.
    In a perfect world without bugs in third-party packages that may be
    defensible (I would still disagree, to be honest). But we don't live in
    a perfect world, packages have bugs and I need to debug them and
    unterstand what they are doing. An error value can never gives you the
    granularity that a verbose debug log can give you.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Axel Wagner at Nov 6, 2015 at 7:36 am

    Nate Finch writes:
    I think the confusion is between packages internal to your application, and
    reusable packages which are intended for general consumption including by
    third parties.
    Not for me :) I'd treat them the same (by applying the higher standards
    to "internal" packages too).
    A reusable package (i.e. something for use with multiple applications, some
    of which may belong to third parties) should never ever log. Imagine if
    encoding/json decided to start logging failed decodes rather than just
    returning an error...
    Imagine encoding/json creating weird output and the only way you have to
    troubleshoot the package or your usage of it, was to clone the source
    and single-step through the debugger. Now contrast that with setting
    json.Debug = log.NewLogger(os.Stderr), rerunning your code and getting a
    detailed view of what encoding/json *thinks* it should do.

    That's my basic point: If I have no way of letting a package output
    debug information, then the only way I have of debugging it or my usage
    of it, is reading the sourcecode, single-stepping a debugger, stracing
    it… I have to resort to black-box debugging, instead of white-box
    debugging. I find that completely annoying.

    I am with you, that maybe no third-party package should log *by
    default*. But I want packages to give me the option of both a coarse "I
    am doing approximately this at he moment, so it's completely fine that
    it takes a while" and a completely verbose "here is a complete trace of
    what I think you wanted me to do". Because depending on the application
    and what I'm currently doing, both might be useful and needed even.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Chris Hines at Nov 7, 2015 at 12:25 am
    There are a lot of good things being said in this thread. As a contributor
    to both log15 and the Go kit logging packages I've spent a fair amount of
    time thinking about many of these issues. I hope the list doesn't mind if I
    provide a few links to my thoughts rather than copy and pasting them.

    With regards to package scoped logging and packages with different sharing
    scopes: https://github.com/go-kit/kit/issues/42.

    On the evolution of the Go kit logging package:
    http://go-talks.appspot.com/github.com/ChrisHines/talks/structured-logging/structured-logging.slide.
    The slides also compare the APIs of several popular logging packages and
    try to make the case for structured logging over Printf based logging.

    Of note, the central interface of Go kit package log is a nicely composable
    one method interface:

    type Logger interface {
    Log(keyvals ...interface{}) error
    }

    Go kit package log docs: https://godoc.org/github.com/go-kit/kit/log.

    Chris
    On Thursday, November 5, 2015 at 11:11:58 PM UTC-5, Nate Finch wrote:

    I think the confusion is between packages internal to your application,
    and reusable packages which are intended for general consumption including
    by third parties.

    Packages that you never intend for anyone outside your application to use
    may log all they want... they're aware of the rules of the application and
    can follow them.

    A reusable package (i.e. something for use with multiple applications,
    some of which may belong to third parties) should never ever log. Imagine
    if encoding/json decided to start logging failed decodes rather than just
    returning an error...

    In these cases, the error is absolutely the right place to return
    information. And yes, it may take some thought for some of the more
    complicated packages out there.... but it's still the only acceptable way
    to communicate.
    On Thursday, November 5, 2015 at 7:54:13 PM UTC-5, Axel Wagner wrote:

    Dave Cheney <da...@cheney.net> writes:
    I don't believe this is true.
    I concede that.

    But you are still taking away the info log-level from non-main packages
    (because returning a non-nil error is considered an error condition, so
    I can't log things that aren't errors). It also seems like a strange
    replacement to logging to me: You are trying to work around the lack of
    good, per-package logging facilities in the stdlib by abusing errors to
    in-band signal the logs. Because what's the difference between returning
    an ErrorWithLoggingInfo and just log to a custom logger, that main can
    choose to replace with a nop-logger if it's not required (or the other
    way around)? From the outside, what happens is, that you get the log
    printed to stderr (or not). And the code for both (from main) will look
    mostly the same too (in regards to
    activating/deactivating/redirecting/whatever
    the logs).
    You can embed line numbers in errors, create a chain of errors with causes,
    and embed stack traces into errors ?

    Have you seen Roger Peppe's errgo package, or juju/errors package which do
    this (albeit with slightly different philosophies) ?

    On Fri, 6 Nov 2015, 07:23 Axel Wagner <axel.wa...@googlemail.com>
    wrote:
    Jakob Borg <ja...@nym.se> writes:
    What James probably means is that you can call log.SetOutput and so
    on
    from your main to affect the default logger.
    However I'd be suspicious in general about a reusable non-main
    package
    doing any kind of logging. In my opinion it should communicate by
    returning an error.
    In a perfect world without bugs in third-party packages that may be
    defensible (I would still disagree, to be honest). But we don't live
    in
    a perfect world, packages have bugs and I need to debug them and
    unterstand what they are doing. An error value can never gives you the
    granularity that a verbose debug log can give you.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Nate Finch at Nov 10, 2015 at 3:46 am
    I loved the slides, Chris. Achieving a tiny interface is truly a worthy
    goal in Go.

    I guess I don't see a huge difference between using gokit's key/value
    interface and just passing a map[string]interface{} to log.Println.

    Can you sell me on the difference?


    On Friday, November 6, 2015 at 7:25:34 PM UTC-5, Chris Hines wrote:

    There are a lot of good things being said in this thread. As a contributor
    to both log15 and the Go kit logging packages I've spent a fair amount of
    time thinking about many of these issues. I hope the list doesn't mind if I
    provide a few links to my thoughts rather than copy and pasting them.

    With regards to package scoped logging and packages with different sharing
    scopes: https://github.com/go-kit/kit/issues/42.

    On the evolution of the Go kit logging package:
    http://go-talks.appspot.com/github.com/ChrisHines/talks/structured-logging/structured-logging.slide.
    The slides also compare the APIs of several popular logging packages and
    try to make the case for structured logging over Printf based logging.

    Of note, the central interface of Go kit package log is a nicely
    composable one method interface:

    type Logger interface {
    Log(keyvals ...interface{}) error
    }

    Go kit package log docs: https://godoc.org/github.com/go-kit/kit/log.

    Chris
    On Thursday, November 5, 2015 at 11:11:58 PM UTC-5, Nate Finch wrote:

    I think the confusion is between packages internal to your application,
    and reusable packages which are intended for general consumption including
    by third parties.

    Packages that you never intend for anyone outside your application to use
    may log all they want... they're aware of the rules of the application and
    can follow them.

    A reusable package (i.e. something for use with multiple applications,
    some of which may belong to third parties) should never ever log. Imagine
    if encoding/json decided to start logging failed decodes rather than just
    returning an error...

    In these cases, the error is absolutely the right place to return
    information. And yes, it may take some thought for some of the more
    complicated packages out there.... but it's still the only acceptable way
    to communicate.
    On Thursday, November 5, 2015 at 7:54:13 PM UTC-5, Axel Wagner wrote:

    Dave Cheney <da...@cheney.net> writes:
    I don't believe this is true.
    I concede that.

    But you are still taking away the info log-level from non-main packages
    (because returning a non-nil error is considered an error condition, so
    I can't log things that aren't errors). It also seems like a strange
    replacement to logging to me: You are trying to work around the lack of
    good, per-package logging facilities in the stdlib by abusing errors to
    in-band signal the logs. Because what's the difference between returning
    an ErrorWithLoggingInfo and just log to a custom logger, that main can
    choose to replace with a nop-logger if it's not required (or the other
    way around)? From the outside, what happens is, that you get the log
    printed to stderr (or not). And the code for both (from main) will look
    mostly the same too (in regards to
    activating/deactivating/redirecting/whatever
    the logs).
    You can embed line numbers in errors, create a chain of errors with causes,
    and embed stack traces into errors ?

    Have you seen Roger Peppe's errgo package, or juju/errors package which do
    this (albeit with slightly different philosophies) ?

    On Fri, 6 Nov 2015, 07:23 Axel Wagner <axel.wa...@googlemail.com>
    wrote:
    Jakob Borg <ja...@nym.se> writes:
    What James probably means is that you can call log.SetOutput and so
    on
    from your main to affect the default logger.
    However I'd be suspicious in general about a reusable non-main
    package
    doing any kind of logging. In my opinion it should communicate by
    returning an error.
    In a perfect world without bugs in third-party packages that may be
    defensible (I would still disagree, to be honest). But we don't live
    in
    a perfect world, packages have bugs and I need to debug them and
    unterstand what they are doing. An error value can never gives you
    the
    granularity that a verbose debug log can give you.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Chris Hines at Nov 10, 2015 at 5:22 am
    The primary benefit is the ability to write composable log formats and
    middle-ware that can operate on typed log event data rather than a byte
    stream. One of my personal favorites from log15 is
    gopkg.in/inconshreveable/log15.v2/ext.EscalateErrHandler
    <https://godoc.org/gopkg.in/inconshreveable/log15.v2/ext#EscalateErrHandler>
    .

    A secondary benefit is having the option not to format the data into a
    []byte immediately.
    On Monday, November 9, 2015 at 10:46:32 PM UTC-5, Nate Finch wrote:

    I loved the slides, Chris. Achieving a tiny interface is truly a worthy
    goal in Go.

    I guess I don't see a huge difference between using gokit's key/value
    interface and just passing a map[string]interface{} to log.Println.

    Can you sell me on the difference?


    On Friday, November 6, 2015 at 7:25:34 PM UTC-5, Chris Hines wrote:

    There are a lot of good things being said in this thread. As a
    contributor to both log15 and the Go kit logging packages I've spent a fair
    amount of time thinking about many of these issues. I hope the list doesn't
    mind if I provide a few links to my thoughts rather than copy and pasting
    them.

    With regards to package scoped logging and packages with different
    sharing scopes: https://github.com/go-kit/kit/issues/42.

    On the evolution of the Go kit logging package:
    http://go-talks.appspot.com/github.com/ChrisHines/talks/structured-logging/structured-logging.slide.
    The slides also compare the APIs of several popular logging packages and
    try to make the case for structured logging over Printf based logging.

    Of note, the central interface of Go kit package log is a nicely
    composable one method interface:

    type Logger interface {
    Log(keyvals ...interface{}) error
    }

    Go kit package log docs: https://godoc.org/github.com/go-kit/kit/log.

    Chris
    On Thursday, November 5, 2015 at 11:11:58 PM UTC-5, Nate Finch wrote:

    I think the confusion is between packages internal to your application,
    and reusable packages which are intended for general consumption including
    by third parties.

    Packages that you never intend for anyone outside your application to
    use may log all they want... they're aware of the rules of the application
    and can follow them.

    A reusable package (i.e. something for use with multiple applications,
    some of which may belong to third parties) should never ever log. Imagine
    if encoding/json decided to start logging failed decodes rather than just
    returning an error...

    In these cases, the error is absolutely the right place to return
    information. And yes, it may take some thought for some of the more
    complicated packages out there.... but it's still the only acceptable way
    to communicate.
    On Thursday, November 5, 2015 at 7:54:13 PM UTC-5, Axel Wagner wrote:

    Dave Cheney <da...@cheney.net> writes:
    I don't believe this is true.
    I concede that.

    But you are still taking away the info log-level from non-main packages
    (because returning a non-nil error is considered an error condition, so
    I can't log things that aren't errors). It also seems like a strange
    replacement to logging to me: You are trying to work around the lack of
    good, per-package logging facilities in the stdlib by abusing errors to
    in-band signal the logs. Because what's the difference between
    returning
    an ErrorWithLoggingInfo and just log to a custom logger, that main can
    choose to replace with a nop-logger if it's not required (or the other
    way around)? From the outside, what happens is, that you get the log
    printed to stderr (or not). And the code for both (from main) will look
    mostly the same too (in regards to
    activating/deactivating/redirecting/whatever
    the logs).
    You can embed line numbers in errors, create a chain of errors with causes,
    and embed stack traces into errors ?

    Have you seen Roger Peppe's errgo package, or juju/errors package which do
    this (albeit with slightly different philosophies) ?

    On Fri, 6 Nov 2015, 07:23 Axel Wagner <axel.wa...@googlemail.com>
    wrote:
    Jakob Borg <ja...@nym.se> writes:
    What James probably means is that you can call log.SetOutput and
    so on
    from your main to affect the default logger.
    However I'd be suspicious in general about a reusable non-main
    package
    doing any kind of logging. In my opinion it should communicate by
    returning an error.
    In a perfect world without bugs in third-party packages that may be
    defensible (I would still disagree, to be honest). But we don't live
    in
    a perfect world, packages have bugs and I need to debug them and
    unterstand what they are doing. An error value can never gives you
    the
    granularity that a verbose debug log can give you.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • James Bardin at Nov 5, 2015 at 7:54 pm

    On Thu, Nov 5, 2015 at 2:08 PM, Axel Wagner wrote:
    But *I* want to SetOutput, SetFlags and SetPrefix. In main.
    I'm not saying it fixes every case, I was only responding the the
    comment about not being able to control logging when a package using
    the log package-level function.

    That's actually the easiest case to control, because anything you set
    in main overrides whatever the packages use (unless they later change
    the logging output again).

    setting log.SetOutput(ioutil.Discard) will silence most packages that
    try to log something.

    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Caleb Spare at Nov 5, 2015 at 3:19 pm

    On Nov 4, 2015 11:38 PM, "'Axel Wagner' via golang-nuts" wrote:
    Hi,

    I am mostly indifferent towards the log package, but just as one note:

    Nate Finch <nate.finch@gmail.com> writes:
    Trace = log.New(ioutil.Discard, "TRACE ", log.LstdFlags)
    This may *seem* like a good idea, but it still means, that the log
    package has to do all the formatting (just to not use it). If log.Logger
    had been an interface, you could replace this with a Logger that truly
    has NOPs.
    Even then, if you put that no op logging in a tight loop, you'll see
    convT2E eating your lunch in profiles. For really efficient noop logging,
    you need an if statement (see the glog approach). (IMO this is one place
    where c-style macros can be quite useful -- they would allow you to
    completely omit code.)
    With the above trivial package, you can now do log.Debug.Printf("foo!")
    just
    like any of the third party loggers.
    But, how is this different from a "third party logger"? It's a trivial
    third party logger, but it's still a package that I have to write or
    import to wrap the stdlib package. It's functionally equivalent.
    I guess the other feature is being able to change levels of logs for
    individual packages, though honestly, in my ~10 years of working on
    projects that use such a feature, I think I've used it all of once or
    twice.
    I believe it would be usefull if this existed (e.g. if every package
    would expose, as a convention or some way of technically requiring it) a
    Debug, Trace, Error… *log.Logger that you could set. I get mightily
    annoyed if third-party packages spam the stderr of my interactive
    program (because that's just bad user experience), but at the same time
    I often encounter errors that I'd like to debug where tracing would be
    very helpfull. xgb is an example of a program that used to use the
    log-package without exposing a knob.

    Another usefull thing (though that's kind of hart to do from the
    language perspective) would be dynamically scoped logging. I would like,
    during tests, to really crank up the verbosity of all packages, but have
    them log to the (*testing.T).Log functions, so that I only see it, if
    something fails. At the same time, this would need to be dynamically
    scoped, so it can't be done via global variables, because that would
    prevent parallel tests which would slow down tests considerably. There
    are ways to cheat your way out of it, though.


    Overall: What is the problem with third party loggers? Why not use a
    package that gives you more power than the stdlib, that's what packages
    are for, after all :)

    Best,

    Axel

    --
    You received this message because you are subscribed to the Google Groups
    "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an
    email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Eric Johnson at Nov 6, 2015 at 6:09 pm
    I really like this thread.

    This strikes me as a great problem for the community to solve. In simple
    cases, so far, I've taken one of the suggestions of this thread, and use
    error returns as an opportunity for the main application to log messages.
    That's a relatively trivial case, though. There are cases where I want to
    log "info" level messages, but continue the normal application flow.

    Ideally, a library (that is, not "main") package will *not* control its own
    logging, and not dictate a logging API. Otherwise, the community starts
    having to pick choices, and that's unfortunate - I've seen this play out in
    the Java world between commons logging, JRE logging, log4j, slf4j, and the
    compatibility issues that you run into when you have to support multiple
    solutions in one application.

    In Go, this could be straightforward - a package should use an interface
    for the logging that it wants, not have it dictated by a third party.
    Since, in Go, this is a relatively trivial exercise to define an interface,
    how about having every package choose its own logging interface?

    This leaves two problems - how should the package define its interface, and
    how does the main application provide an implementation of that interface?

    I think the package can define its interface in one of two ways - either a
    wide interface or a narrow one.

    The wide interface would need methods like "Debug()", "Error()", "Info()",
    "Warn()", and possibly also "IsDebugging()", "IsErroring()", "IsInfoing()",
    and "IsWarning()" - the latter set of functions so that package authors can
    bracket possibly expensive logging operations with an if block to avoid
    them if not needed. Invocations look like:

    if log.IsDebugging() {
       log.Debug(...)
    }

    The narrow interface might be just a pair of methods - "Log()", and
    "IsActive()", and then the library gets a separate instance for each of the
    levels of logging it wants.

    In this case, the log calls look like:
    if debug.IsActive() {
       debug.Log(...)
    }

    A package level configuration of the logging for the latter pattern look
    like this:

    func SetLogging(debug, info, warn error Log) {
      ...
    }

    I sort of like the latter, narrower interface more - seems more idiomatic.
    But I think it works either way, because the package author doesn't need to
    choose!

    The next challenge is this - how does the main application provide a logger
    for the library package to use? Three options that I see:
    1) Explicit parameters to objects. Good because main package has full
    control. Bad, because it widens the API, and if the package is buried
    several levels deep in dependencies, that could be awkward. This might
    depend on whether the package defines objects that will be instantiated
    with different logging configurations for different parts of the
    application. Seems like a rare case.

    2) Package level method to set logging configuration (see the example
    above). Even better if the package sets a reasonable default - perhaps
    using the standard logging package. Now the main package can override the
    default logging if it wants, or it can just let the package do what it
    wants.

    3) Package registers with a logging API. The main application defines how
    each logging API is satisfied. I'm waving my hands a little, but the
    up-side of central registration is that once the Go ecosystem settles on a
    few patterns, this registration library could deal with loading
    configuration on behalf of the main package. It could use reflect to
    identify the types of the interfaces being requested, and map that to the
    actual logging library being used.

    Seems like #2 is the natural place for the community to start.

    And, having kicked the problem to the "main" package, now the community can
    build infrastructure around dynamically changing the provider loggers based
    on a configuration file.

    Eric.
    On Wednesday, November 4, 2015 at 7:40:52 PM UTC-8, Nate Finch wrote:

    I see a lot of hate directed at the stdlib's log package, and of course,
    there are a medley of third party logging packages. What are people's
    problems with the standard log package? I've seen accusations that it
    doesn't have leveled logging, which seems like an exercise in laziness,
    because that's easy to write:

    package logimport (
    "io/ioutil"
    "log"
    "os"
    )
    var (
    Trace = log.New(ioutil.Discard, "TRACE ", log.LstdFlags)
    Debug = log.New(os.Stdout, "DEBUG ", log.LstdFlags)
    // etc
    )

    With the above trivial package, you can now do log.Debug.Printf("foo!") just
    like any of the third party loggers.

    Some loggers are structured loggers, which again seems like not a big
    deal, you can pass a map[string]interface{} into log.Printf and it'll print
    out the map in a fairly easily parse-able way...

    The only thing I can think of is that the time formatting is kinda ugly. I
    guess the other feature is being able to change levels of logs for
    individual packages, though honestly, in my ~10 years of working on
    projects that use such a feature, I think I've used it all of once or twice.

    What am I missing?
    --
    You received this message because you are subscribed to the Google Groups "golang-nuts" group.
    To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 5, '15 at 3:40a
activeNov 25, '15 at 12:21p
posts28
users13
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase