aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/log/log.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/log/log.go')
-rw-r--r--libgo/go/log/log.go101
1 files changed, 69 insertions, 32 deletions
diff --git a/libgo/go/log/log.go b/libgo/go/log/log.go
index 658e3bd..33140ee 100644
--- a/libgo/go/log/log.go
+++ b/libgo/go/log/log.go
@@ -28,11 +28,12 @@ const (
// order they appear (the order listed here) or the format they present (as
// described in the comments). A colon appears after these items:
// 2009/0123 01:23:23.123123 /a/b/c/d.go:23: message
- Ldate = 1 << iota // the date: 2009/0123
- Ltime // the time: 01:23:23
- Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
- Llongfile // full file name and line number: /a/b/c/d.go:23
- Lshortfile // final file name element and line number: d.go:23. overrides Llongfile
+ Ldate = 1 << iota // the date: 2009/0123
+ Ltime // the time: 01:23:23
+ Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
+ Llongfile // full file name and line number: /a/b/c/d.go:23
+ Lshortfile // final file name element and line number: d.go:23. overrides Llongfile
+ LstdFlags = Ldate | Ltime // initial values for the standard logger
)
// A Logger represents an active logging object that generates lines of
@@ -40,10 +41,11 @@ const (
// the Writer's Write method. A Logger can be used simultaneously from
// multiple goroutines; it guarantees to serialize access to the Writer.
type Logger struct {
- mu sync.Mutex // ensures atomic writes
- out io.Writer // destination for output
- prefix string // prefix to write at beginning of each line
- flag int // properties
+ prefix string // prefix to write at beginning of each line
+ flag int // properties
+ mu sync.Mutex // ensures atomic writes; protects the following fields
+ out io.Writer // destination for output
+ buf bytes.Buffer // for accumulating text to write
}
// New creates a new Logger. The out variable sets the
@@ -54,7 +56,7 @@ func New(out io.Writer, prefix string, flag int) *Logger {
return &Logger{out: out, prefix: prefix, flag: flag}
}
-var std = New(os.Stderr, "", Ldate|Ltime)
+var std = New(os.Stderr, "", LstdFlags)
// Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding.
// Knows the buffer has capacity.
@@ -81,7 +83,7 @@ func itoa(buf *bytes.Buffer, i int, wid int) {
}
}
-func (l *Logger) formatHeader(buf *bytes.Buffer, ns int64, calldepth int) {
+func (l *Logger) formatHeader(buf *bytes.Buffer, ns int64, file string, line int) {
buf.WriteString(l.prefix)
if l.flag&(Ldate|Ltime|Lmicroseconds) != 0 {
t := time.SecondsToLocalTime(ns / 1e9)
@@ -107,21 +109,15 @@ func (l *Logger) formatHeader(buf *bytes.Buffer, ns int64, calldepth int) {
}
}
if l.flag&(Lshortfile|Llongfile) != 0 {
- _, file, line, ok := runtime.Caller(calldepth)
- if ok {
- if l.flag&Lshortfile != 0 {
- short := file
- for i := len(file) - 1; i > 0; i-- {
- if file[i] == '/' {
- short = file[i+1:]
- break
- }
+ if l.flag&Lshortfile != 0 {
+ short := file
+ for i := len(file) - 1; i > 0; i-- {
+ if file[i] == '/' {
+ short = file[i+1:]
+ break
}
- file = short
}
- } else {
- file = "???"
- line = 0
+ file = short
}
buf.WriteString(file)
buf.WriteByte(':')
@@ -138,15 +134,26 @@ func (l *Logger) formatHeader(buf *bytes.Buffer, ns int64, calldepth int) {
// paths it will be 2.
func (l *Logger) Output(calldepth int, s string) os.Error {
now := time.Nanoseconds() // get this early.
- buf := new(bytes.Buffer)
- l.formatHeader(buf, now, calldepth+1)
- buf.WriteString(s)
- if len(s) > 0 && s[len(s)-1] != '\n' {
- buf.WriteByte('\n')
+ // get caller info (if required) before locking - it's expensive.
+ var file string
+ var line int
+ if l.flag&(Lshortfile|Llongfile) != 0 {
+ var ok bool
+ _, file, line, ok = runtime.Caller(calldepth)
+ if !ok {
+ file = "???"
+ line = 0
+ }
}
l.mu.Lock()
defer l.mu.Unlock()
- _, err := l.out.Write(buf.Bytes())
+ l.buf.Reset()
+ l.formatHeader(&l.buf, now, file, line)
+ l.buf.WriteString(s)
+ if len(s) > 0 && s[len(s)-1] != '\n' {
+ l.buf.WriteByte('\n')
+ }
+ _, err := l.out.Write(l.buf.Bytes())
return err
}
@@ -203,19 +210,49 @@ func (l *Logger) Panicln(v ...interface{}) {
panic(s)
}
+// Flags returns the output flags for the logger.
+func (l *Logger) Flags() int {
+ return l.flag
+}
+
+// SetFlags sets the output flags for the logger.
+func (l *Logger) SetFlags(flag int) {
+ l.flag = flag
+}
+
+// Prefix returns the output prefix for the logger.
+func (l *Logger) Prefix() string {
+ return l.prefix
+}
+
+// SetPrefix sets the output prefix for the logger.
+func (l *Logger) SetPrefix(prefix string) {
+ l.prefix = prefix
+}
+
// SetOutput sets the output destination for the standard logger.
func SetOutput(w io.Writer) {
std.out = w
}
+// Flags returns the output flags for the standard logger.
+func Flags() int {
+ return std.Flags()
+}
+
// SetFlags sets the output flags for the standard logger.
func SetFlags(flag int) {
- std.flag = flag
+ std.SetFlags(flag)
+}
+
+// Prefix returns the output prefix for the standard logger.
+func Prefix() string {
+ return std.Prefix()
}
// SetPrefix sets the output prefix for the standard logger.
func SetPrefix(prefix string) {
- std.prefix = prefix
+ std.SetPrefix(prefix)
}
// These functions write to the standard logger.