Git Product home page Git Product logo

Comments (11)

deankarn avatar deankarn commented on September 27, 2024

hello @codeskyblue

yes you can use it as a simple log, if you need that exact output I'd just create a new handler ( code provided below ).

As for having the filename and line number, because my handlers run in goroutines, I can't just call runtime.Caller to get that information, however, I could store that information on the Entry Object that gets passed to the handlers. I will look at the best way to implement this and add an option to turn this functionality on as some may not want it as calling runtime.Caller does have overhead.

Thanks for the idea! 😄

package simple

import (
    "fmt"
    "io"
    "os"
    "time"

    "github.com/go-playground/log"
)

const (
    timestampFormat = "2006-01-02 15:04:05"
)

// Console is an instance of the console logger
type Console struct {
    buffer uint
    writer io.Writer
    start  time.Time
}

// New returns a new instance of the console logger
func New() *Console {
    return &Console{
        buffer: 0,
        writer: os.Stderr,
        start:  time.Now(),
    }
}

// SetWriter sets Console's wriiter
// Default is : os.Stderr
func (c *Console) SetWriter(w io.Writer) {
    c.writer = w
}

// SetChannelBuffer tells Console what the channel buffer size should be
// Default is : 0
func (c *Console) SetChannelBuffer(i uint) {
    c.buffer = i
}

// Run starts the logger consuming on the returned channed
func (c *Console) Run() chan<- *log.Entry {

    // in a big high traffic app, set a higher buffer
    ch := make(chan *log.Entry, c.buffer)

    go c.handleLog(ch)

    return ch
}

// handleLog consumes and logs any Entry's passed to the channel and
// print with no color
func (c *Console) handleLog(entries <-chan *log.Entry) {

    var e *log.Entry

    for e = range entries {

        if len(e.Fields) == 0 {
            fmt.Fprintf(c.writer, "%s  %6s %s", e.Timestamp.Format(timestampFormat), e.Level, e.Message)
        } else {
            fmt.Fprintf(c.writer, "%s  %6s %-25s", e.Timestamp.Format(timestampFormat), e.Level, e.Message)
        }

        for _, f := range e.Fields {
            fmt.Fprintf(c.writer, " %s=%v", f.Key, f.Value)
        }

        fmt.Fprintln(c.writer)

        e.WG.Done()
    }
}

from log.

codeskyblue avatar codeskyblue commented on September 27, 2024

if this implemented. I would very happy to change the default log to this one.

this is one log looks good. github.com/qiniu/log

from log.

deankarn avatar deankarn commented on September 27, 2024

I will definitely add add the file + line number logic, just give me a few days and I'll let you know when it's all done.

from log.

codeskyblue avatar codeskyblue commented on September 27, 2024

@joeybloggs sure, I'll wait.

from log.

deankarn avatar deankarn commented on September 27, 2024

Hey @codeskyblue

changes have been made and are in Release 1.4

Turning capturing on:

// NOTE: this must be set prior to registering any handlers
// as the handlers may call log.GetCallerInfo() to determine 
// their output while being registered
log.SetCallerInfo(true)

code for your desired output:

package simple

import (
    "fmt"
    "io"
    "os"
    "time"

    "github.com/go-playground/log"
)

const (
    timestampFormat = "2006-01-02 15:04:05"
    format = "%s  %6s %s:%d %s"
    formatFields = "%s  %6s %s:%d %-25s"
)

// Console is an instance of the console logger
type Console struct {
    buffer uint
    writer io.Writer
    start  time.Time
}

// New returns a new instance of the console logger
func New() *Console {
    return &Console{
        buffer: 0,
        writer: os.Stderr,
        start:  time.Now(),
    }
}

// SetWriter sets Console's wriiter
// Default is : os.Stderr
func (c *Console) SetWriter(w io.Writer) {
    c.writer = w
}

// SetChannelBuffer tells Console what the channel buffer size should be
// Default is : 0
func (c *Console) SetChannelBuffer(i uint) {
    c.buffer = i
}

// Run starts the logger consuming on the returned channed
func (c *Console) Run() chan<- *log.Entry {

    // in a big high traffic app, set a higher buffer
    ch := make(chan *log.Entry, c.buffer)

    go c.handleLog(ch)

    return ch
}

// handleLog consumes and logs any Entry's passed to the channel and
// print with no color
func (c *Console) handleLog(entries <-chan *log.Entry) {

    var e *log.Entry
    var file string

    for e = range entries {

        file = e.File
    for i := len(file) - 1; i > 0; i-- {
        if file[i] == '/' {
            file = file[i+1:]
            break
        }
    }

        if len(e.Fields) == 0 {
            fmt.Fprintf(c.writer, format, e.Timestamp.Format(timestampFormat), e.Level,file, e.Line, e.Message)
        } else {
            fmt.Fprintf(c.writer, formatFields, e.Timestamp.Format(timestampFormat), e.Level,file, e.Line e.Message)
        }

        for _, f := range e.Fields {
            fmt.Fprintf(c.writer, " %s=%v", f.Key, f.Value)
        }

        fmt.Fprintln(c.writer)

        e.Consumed()
    }
}

Let me know if this works for you and I'll close the issue.

from log.

codeskyblue avatar codeskyblue commented on September 27, 2024

In this way, I still have to write a lot of code myself.

This is my environment

package main

import "github.com/go-playground/log"

func main() {
    log.Info("Hello")
}

expect output

2016/05/02 12:20:11 [INFO] test.go:6: Hello

Actually got

Yeah, nothing output found.

from log.

deankarn avatar deankarn commented on September 27, 2024

You can use the built in console handler, just have to set a few settings to get your desired output, like below(will be adding a custom formatter to console handler like the syslog one in the future):

clog.DisplayColor(false)
clog.SetTimestampFormat("2006-01-02 15:04:05")
log.SetCallerInfo(true)
log.RegisterHandler(clog, log.AllLevels...)

As for why you got no answer output, you never registered a handler to log with; please see the example both in the README and here. There is no default handler because don't want to force anybody to use a handler they may not want to use. You only have to register the handler once, within your main package because "log" is a singleton.

from log.

codeskyblue avatar codeskyblue commented on September 27, 2024

How about if no handler found, then use use the default console handler.

from log.

deankarn avatar deankarn commented on September 27, 2024

There are many reasons I decided to not include a default logger, but the main three are:

  • I want to keep the handlers and log loosly coupled. The handlers should know about log but,log shouldn't know about available handlers.
  • keeping the log package simple, the user should choose what they want; the log package shouldn't guess
  • in most cases users will be adding or tweaking handlers based on their run mode anyways I.e. more handlers in production mode like syslog but consoleonly for development or even as simple as color output during development, buy plain in production.

I will think about it further but don't think I'm likely to change my mind; besides it's only 2 lines to add the console handler.

clog := console.New()
log.Registerhandler (clog, log.AllLevels...)

from log.

codeskyblue avatar codeskyblue commented on September 27, 2024

Actually not only two lines. Got four lines actually

clog.DisplayColor(false)
clog.SetTimestampFormat("2006-01-02 15:04:05")
log.SetCallerInfo(true)
log.RegisterHandler(clog, log.AllLevels...)

BTW: SetCallerInfo seems not working( I use the latest master branch code)

I agree that the implemented code should be simple. but the usage can be also simple. like python logging library. I can use it with more complex way and I can also use more simple way.

logging.info("hello world")

I have seen many other log libraries, but I choose the buildin log library finally. The two main reason is

  1. simple
  2. stable

from log.

deankarn avatar deankarn commented on September 27, 2024

yes 4 lines, because you don't want colour, a specific date format and file + line number, that's not a fault of this library, and is a testament to the default console handler that it lets you easily change those two things. You could use the code I provided you above and then wouldn't have to call DisplayColor(..) and SetTimestampFormat(...).

SetCallerInfo is definitely working for me, using to debug a program as I write this, do you have a code sample of how you're using it?

I mean no offense by this, but it seems like you are judging solely based on the fact that I don't provide a default handler and that you having to type a few lines of code to get your desired output. The log library is simple, just not out of the box exactly what you want or how you believe it should work; which is fine, but it does provide the flexibility to log however you want.

The std log library is great, and you will be able to implement what you want using its MultiWriter functionality and adding log levels; best wishes 😄

from log.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.