Comments (11)
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.
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.
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.
@joeybloggs sure, I'll wait.
from log.
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.
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.
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.
How about if no handler found, then use use the default console handler.
from log.
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.
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
- simple
- stable
from log.
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)
- Help Wanted - adding more log Handlers HOT 2
- UTC time HOT 2
- group entries HOT 4
- is there anyway to define logging time? e.g. use Local Time instead of UTC HOT 1
- Not all error prefixes make it to the logging field
- Unable to remove handlers HOT 2
- Synchronization HOT 7
- Ability to change or disable log levels HOT 3
- Ability to disable the email handler from sending emails HOT 1
- cannot use syscall.Stdout as type int in argument to terminal.IsTerminal HOT 3
- Windows color HOT 2
- Every visit add a line ....
- Cannot use in a module based project HOT 2
- Go playground issue HOT 4
- Gather file + line info on all error type logs
- v8 How to turn off the default output HOT 2
- Add configurable skip level for file + line number
- SetFormatFunc is useless HOT 4
- Sharing fields between entries HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from log.