func Error(msg string) { switch { case *logType == "stderr": glog.Errorln(msg) case *logType == "syslog": syslog.Err(msg) } }
// output writes the data to the log files and releases the buffer. func (l *loggingT) output(s severity, buf *buffer) { l.mu.Lock() if l.traceLocation.isSet() { _, file, line, ok := runtime.Caller(3) // It's always the same number of frames to the user's call (same as header). if ok && l.traceLocation.match(file, line) { buf.Write(stacks(false)) } } data := buf.Bytes() if l.toStderr { os.Stderr.Write(data) } if l.toSyslog { switch s { case fatalLog: syslog.Emerg(string(data)) case errorLog: syslog.Err(string(data)) case warningLog: syslog.Warning(string(data)) case infoLog: syslog.Info(string(data)) } } if l.toFile { // JTODO: CONVERT TO JUST MIN THRESHOLD, NOT STDERR THRESHOLD // if s >= l.stderrThreshold.get() { // os.Stderr.Write(data) // } if l.file[s] == nil { if err := l.createFiles(s); err != nil { os.Stderr.Write(data) // Make sure the message appears somewhere. l.exit(err) } } switch s { case fatalLog: l.file[fatalLog].Write(data) case errorLog: l.file[errorLog].Write(data) case warningLog: l.file[warningLog].Write(data) case infoLog: l.file[infoLog].Write(data) } } if s == fatalLog { // Make sure we see the trace for the current goroutine on standard error. if !l.toStderr { os.Stderr.Write(stacks(false)) } // Write the stack trace for all goroutines to the files. trace := stacks(true) logExitFunc = func(error) {} // If we get a write error, we'll still exit below. for log := fatalLog; log >= infoLog; log-- { if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set. f.Write(trace) } } l.mu.Unlock() timeoutFlush(10 * time.Second) os.Exit(255) // C++ uses -1, which is silly because it's anded with 255 anyway. } l.putBuffer(buf) l.mu.Unlock() if stats := severityStats[s]; stats != nil { atomic.AddInt64(&stats.lines, 1) atomic.AddInt64(&stats.bytes, int64(len(data))) } }