亡羊补牢,为时未晚
不知从哪里曾经听过一句话,程序员的日常工作不是在修bug,就是在创造bug的路上。衡量一个程序员的功力如何,不仅要看他掌握的知识的广度和深度,最重要的是要看他发现问题、定位问题、解决问题的效率。一般作坊式公司的程序员群体,因为技术实力的限制,通常一个项目主要是以功能数据流跑通为主,至于一些细节性的东西,通常关注的并不多,如果项目出了问题,他们的第一反应是本地浮现问题,然后开启debug模式,不要问为什么不看日志,理由是:开发的过程中压根就没有在代码中打日志,出了问题只能靠猜和蒙。
go语言的log包
go语言的log包主要提供了一些操作log的函数和方法,下面将针对这些函数和方法展开讲解。
package main
/*********************************************************************/
/**************** golang中log包相关API讲解 *************************/
/*******************************************************************/
/*
Constants
func Fatal(v ...interface{})
func Fatalf(format string, v ...interface{})
func Fatalln(v ...interface{})
func Flags() int
func Output(calldepth int, s string) error
func Panic(v ...interface{})
func Panicf(format string, v ...interface{})
func Panicln(v ...interface{})
func Prefix() string
func Print(v ...interface{})
func Printf(format string, v ...interface{})
func Println(v ...interface{})
func SetFlags(flag int)
func SetOutput(w io.Writer)
func SetPrefix(prefix string)
func Writer() io.Writer
type Logger
func Default() *Logger
func New(out io.Writer, prefix string, flag int) *Logger
func (l *Logger) Fatal(v ...interface{})
func (l *Logger) Fatalf(format string, v ...interface{})
func (l *Logger) Fatalln(v ...interface{})
func (l *Logger) Flags() int
func (l *Logger) Output(calldepth int, s string) error
func (l *Logger) Panic(v ...interface{})
func (l *Logger) Panicf(format string, v ...interface{})
func (l *Logger) Panicln(v ...interface{})
func (l *Logger) Prefix() string
func (l *Logger) Print(v ...interface{})
func (l *Logger) Printf(format string, v ...interface{})
func (l *Logger) Println(v ...interface{})
func (l *Logger) SetFlags(flag int)
func (l *Logger) SetOutput(w io.Writer)
func (l *Logger) SetPrefix(prefix string)
func (l *Logger) Writer() io.Writer
*/
func main() {
// Print类:跟fmt差不多,只是前面加了格式
// Fatal类:日志输出后,系统调用os.exit(1),整个程序退出。如果后面有defer,也不执行
// Panic类:日志输出后,发生Panic
/**
*Fatal等价于{Print(v...); os.Exit(1)}
*func Fatal(v ...interface{})
*/
/*
log.Fatal("hello啊树先生,执行后终止")
fmt.Println("你执行了吗?")
*/
/**
*Fatalf等价于{Printf(v...); os.Exit(1)}
*func Fatalf(format string, v ...interface{})
*/
/*
log.Fatalf("hello树先生带格式的日志执行后终止")
fmt.Println("你执行了吗?")
*/
/**
*Fatalln等价于{Println(v...); os.Exit(1)}
*func Fatalln(v ...interface{})
*/
/*
log.Fatalf("hello树先生带格式的日志执行并换行后终止")
fmt.Println("你执行了吗?")
*/
/**
*Flags返回标准logger的输出选项。
*func Flags() int
*/
/*
n := log.Flags()
fmt.Println(n)
*/
/**
*Output写入输出一次日志事件。参数s包含在Logger根据选项生成的前缀之后要打印的文本。
*如果s末尾没有换行会添加换行符。calldepth用于恢复PC,出于一般性而提供,但目前在
*所有预定义的路径上它的值都为2。
*func Output(calldepth int, s string) error
*/
/*
var (
buf bytes.Buffer
logger = log.New(&buf, "INFO: ", log.Lshortfile)
infof = func(info string) {
logger.Output(2, info)
}
)
infof("Hello world")
fmt.Print(&buf)
*/
/**
*Panic等价于{Print(v...); panic(...)}
*func Panic(v ...interface{})
*/
/*
log.Panic("打印之后发生panic")
*/
/**
*Panicf等价于{Printf(v...); panic(...)}
*func Panicf(format string, v ...interface{})
*/
/*
log.Panicf("%s", "格式化输出后在发生panic")
*/
/**
*Panicln等价于{Println(v...); panic(...)}
*func Panicln(v ...interface{})
*/
/*
log.Panicln("输出后换行在发生panic")
*/
/**
*Prefix返回标准logger的输出前缀。
*func Prefix() string
*/
/*
log.SetPrefix("【hello啊树先生】")
s := log.Prefix()
fmt.Println(s)
*/
/**
*Print调用Output将生成的格式化字符串输出到标准logger,参数用和fmt.Print相同的方法处理。
*func Print(v ...interface{})
*/
/*
log.Print("日志的标准输出")
*/
/**
*Printf调用Output将生成的格式化字符串输出到标准logger,参数用和fmt.Printf相同的方法处理。
*func Printf(format string, v ...interface{})
*/
/*
log.Printf("%s", "日志的格式化标准输出")
*/
/**
*Println调用Output将生成的格式化字符串输出到标准logger,参数用和fmt.Println相同的方法处理。
*func Println(v ...interface{})
*/
/*
log.Println("日志的标准话输出并换行")
*/
/**
*SetFlags设置标准logger的输出选项。
*func SetFlags(flag int)
*/
/*
log.SetFlags(log.Ldate|log.Ltime |log.LUTC)
log.Println("sddfgfgh")
*/
/**
*SetFlags设置标准logger的输出选项。
*SetOutput设置标准logger的输出目的地,默认是标准错误输出。
*/
/*
file, _ := os.Create("sdk/testLog")
log.SetOutput(file)
*/
/**
*SetPrefix设置标准logger的输出前缀。
*func SetPrefix(prefix string)
*/
/*
log.SetPrefix("【hello啊树先生】")
s := log.Prefix()
fmt.Println(s)
*/
/**
*SetPrefix设置标准logger的输出前缀。
*func Writer() io.Writer
*/
/*********************************************************************/
/**************** Logger相关方法讲解 ********************************/
/********************************************************************/
/**
*输出标准的包水平定义的日志
*func Default() *Logger
*/
/*
logger := log.Default()
*/
/**
*New创建一个Logger。参数out设置日志信息写入的目的地。参数prefix会添加到生成的每一条日志前面。
×参数flag定义日志的属性(时间、文件等等)。
*func New(out io.Writer, prefix string, flag int) *Logger
*/
/*
file, _ := os.Create("sdk/testLog")
log.New(file, "【info】", log.Ldate|log.Ltime|log.Lshortfile)
*/
/**
*Fatal等价于{l.Print(v...); os.Exit(1)}
*func (l *Logger) Fatal(v ...interface{})
*/
/*
var (
buf bytes.Buffer
logger = log.New(&buf, "logger: ", log.Lshortfile)
)
fmt.Print(&buf)
logger.Fatal("Hello, log file!")
*/
/**
*Fatalf等价于{l.Printf(v...); os.Exit(1)}
*func (l *Logger) Fatalf(format string, v ...interface{})
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
logger.Fatalf("%s", "格式化输出并终止程序")
*/
/**
*Fatalln等价于{l.Println(v...); os.Exit(1)}
*func (l *Logger) Fatalln(v ...interface{})
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
logger.Fatalln("执行输出并换行后终止程序")
*/
/**
*Flags返回logger的输出选项。
*func (l *Logger) Flags() int
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
fmt.Println(logger.Flags())
*/
/**
*Output写入输出一次日志事件。参数s包含在Logger根据选项生成的前缀之后要打印的文本。
*如果s末尾没有换行会添加换行符。calldepth用于恢复PC,出于一般性而提供,但目前在
*所有预定义的路径上它的值都为2。
*func (l *Logger) Output(calldepth int, s string) error
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
err := logger.Output(10, "hello")
fmt.Println(err)
*/
/**
*Panic等价于{l.Print(v...); panic(...)}
*func (l *Logger) Panic(v ...interface{})
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
logger.Panic("输出日志之后发生panic")
*/
/**
*Panicf等价于{l.Printf(v...); panic(...)}
*func (l *Logger) Panicf(format string, v ...interface{})
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
logger.Panicf("%s","格式化输出之后发生panic")
*/
/**
*Panicln等价于{l.Println(v...); panic(...)}
*func (l *Logger) Panicln(v ...interface{})
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
logger.Panicln("输出panic之后并换行")
*/
/**
*Prefix返回logger的输出前缀。
*func (l *Logger) Prefix() string
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
prefix := logger.Prefix()
fmt.Println(prefix)
*/
/**
*Print调用l.Output将生成的格式化字符串输出到logger,参数用和fmt.Print相同的方法处理。
*func (l *Logger) Print(v ...interface{})
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
logger.Print("输出日志不换行")
*/
/**
*Printf调用l.Output将生成的格式化字符串输出到logger,参数用和fmt.Printf相同的方法处理。
*func (l *Logger) Printf(format string, v ...interface{})
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
logger.Printf("%s", "格式化输出日志")
*/
/**
*Println调用l.Output将生成的格式化字符串输出到logger,参数用和fmt.Println相同的方法处理。
*func (l *Logger) Println(v ...interface{})
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
logger.Println("输出日志之后进行换行")
*/
/**
*SetFlags设置logger的输出选项。
*func (l *Logger) SetFlags(flag int)
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
logger.SetFlags(1)
*/
/**
*SetOutput设置日志的输出目标。
*func (l *Logger) SetOutput(w io.Writer)
*/
/*
var (
buf bytes.Buffer
logger = log.New(&buf, "INFO: ", log.Lshortfile)
infof = func(info string) {
logger.Output(2, info)
}
)
infof("Hello world")
fmt.Print(&buf)
*/
/**
*SetPrefix设置logger的输出前缀。
*func (l *Logger) SetPrefix(prefix string)
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
logger.SetPrefix("【prefix】")
logger.Print("hello树先生前缀")
*/
/**
*Writer返回日志的输出目标。
*func (l *Logger) Writer() io.Writer
*/
/*
var logger = log.New(os.Stdout, "logger: ", log.Lshortfile)
logger.Writer()
*/
}
小结
log包部分的内容相对而言还是比较少的,掌握起来应该是比较容易的,一个设计成功的系统,日志模块肯定是必不可少的一环,相应的相关的方法函数也是必然需要掌握的。