123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- // Copyright 2017 Unknwon
- //
- // Licensed under the Apache License, Version 2.0 (the "License"): you may
- // not use this file except in compliance with the License. You may obtain
- // a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- // License for the specific language governing permissions and limitations
- // under the License.
- // Clog is a channel-based logging package for Go.
- package clog
- import (
- "fmt"
- "os"
- "path/filepath"
- "runtime"
- "strings"
- )
- const (
- _VERSION = "1.1.0"
- )
- // Version returns current version of the package.
- func Version() string {
- return _VERSION
- }
- type (
- MODE string
- LEVEL int
- )
- const (
- TRACE LEVEL = iota
- INFO
- WARN
- ERROR
- FATAL
- )
- var formats = map[LEVEL]string{
- TRACE: "[TRACE] ",
- INFO: "[ INFO] ",
- WARN: "[ WARN] ",
- ERROR: "[ERROR] ",
- FATAL: "[FATAL] ",
- }
- // isValidLevel returns true if given level is in the valid range.
- func isValidLevel(level LEVEL) bool {
- return level >= TRACE && level <= FATAL
- }
- // Message represents a log message to be processed.
- type Message struct {
- Level LEVEL
- Body string
- }
- func Write(level LEVEL, skip int, format string, v ...interface{}) {
- msg := &Message{
- Level: level,
- }
- // Only error and fatal information needs locate position for debugging.
- // But if skip is 0 means caller doesn't care so we can skip.
- if msg.Level >= ERROR && skip > 0 {
- pc, file, line, ok := runtime.Caller(skip)
- if ok {
- // Get caller function name.
- fn := runtime.FuncForPC(pc)
- var fnName string
- if fn == nil {
- fnName = "?()"
- } else {
- fnName = strings.TrimLeft(filepath.Ext(fn.Name()), ".") + "()"
- }
- if len(file) > 20 {
- file = "..." + file[len(file)-20:]
- }
- msg.Body = formats[level] + fmt.Sprintf("[%s:%d %s] ", file, line, fnName) + fmt.Sprintf(format, v...)
- }
- }
- if len(msg.Body) == 0 {
- msg.Body = formats[level] + fmt.Sprintf(format, v...)
- }
- for i := range receivers {
- if receivers[i].Level() > level {
- continue
- }
- receivers[i].msgChan <- msg
- }
- }
- func Trace(format string, v ...interface{}) {
- Write(TRACE, 0, format, v...)
- }
- func Info(format string, v ...interface{}) {
- Write(INFO, 0, format, v...)
- }
- func Warn(format string, v ...interface{}) {
- Write(WARN, 0, format, v...)
- }
- func Error(skip int, format string, v ...interface{}) {
- Write(ERROR, skip, format, v...)
- }
- func Fatal(skip int, format string, v ...interface{}) {
- Write(FATAL, skip, format, v...)
- Shutdown()
- os.Exit(1)
- }
- func Shutdown() {
- for i := range receivers {
- receivers[i].Destroy()
- }
- // Shutdown the error handling goroutine.
- quitChan <- struct{}{}
- for {
- if len(errorChan) == 0 {
- break
- }
- fmt.Printf("clog: unable to write message: %v\n", <-errorChan)
- }
- }
|