Go 2.0 该如何满足开发者的期待?( 三 )


Go标准库需要定义一个结构化的日志接口 , 现有的上游包都可以选择实现该接口 。 然后 , 作为库作者 , 我可以选择接受 log.StructuredLogger 接口 , 实现者可以自己选择:

func WithLogger(l log.StructuredLogger) Option {return func(f *Foo) *Foo{f.logger = lreturn f}}
我快速整理了一个潦草的接口:
// StructuredLogger is an interface for structured logging.type StructuredLogger interface {// Log logs a message.Log(message string, fields...LogField)
// LogAt logs a messageat the provided level. Perhaps we could also have// Debugf, Infof, etc,but I think that might be too limiting for the standard// library.LogAt(level LogLevel,message string, fields ...LogField)
// LogEntry logs acomplete log entry. See LogEntry for the default values if// any fields aremissing.LogEntry(entry*LogEntry)}
// LogLevel is the underlying log level.type LogLevel uint8
// LogEntry represents a single log entry.type LogEntry struct {// Level is the loglevel. If no level is provided, the default level of// LevelError is used.Level LogLevel
// Message is the actuallog message.Message string
// Fields is the list ofstructured logging fields. If two fields have the same// Name, the later onetakes precedence.Fields []*LogField}
// LogField is a tuple of the named field (a string) and itsunderlying value.type LogField struct {Name stringValue interface{}}
围绕具体的接口、如何最小化资源分配以及最大化兼容性的讨论有很多 , 但目标都是定义一个其他日志库可以轻松实现的接口 。
回到我从事 Ruby 开发的时代 , 有一阵子 Ruby 的版本管理器激增 , 每个版本管理器的配置文件名和语法都不一样 。 Fletcher Nichol 写了一篇 gist , 成功地说服所有 Ruby 版本管理器的维护者对 .ruby-version 进行标准化 。 我希望 Go 社区也能以类似的方式处理结构化日志 。
多错误处理
在很多情况下 , 尤其是后台作业或周期性任务 , 系统可能会并行处理多个任务或采用continue-on-error策略 。 在这些情况下 , 返回多个错误会很有帮助 。 标准库中没有处理错误集合的内置支持 。
Go社区可以围绕多错误处理建立清晰简洁的标准库 , 这样不仅可以统一社区 , 而且还可以降低错误处理不当的风险 , 就好象错误打包和展开那样 。
对于error的JSON序列化处理
说到错误 , 你知不知道如果将 error 类型嵌入到结构字段中 , 然后将这个结构进行JSON序列化 , "error"就会被序列化成{}?
// https://play.golang.org/p/gl7BPJOgmjrpackage main
import ("encoding/json""fmt")
type Response1 struct {Err error`json:"error"`}
func main {v1 :=&Response1{Err: fmt.Errorf("oops")}b1, err :=json.Marshal(v1)if err != nil {panic(err)}
// got:{"error":{}}// want: {"error": "oops"}fmt.Println(string(b1))}
至少对于内置的 errorString 类型 , Go应当对.Error的结果进行序列化 。 或者在 Go 2.0 中 , 也可以在试图对 error 类型进行序列化时 , 如果没有定义序列化逻辑 , 则返回错误 。
标准库中不再有公共变量
仅举一个例子 , http.DefaultClient 和 http.DefaultTransport 都是具有共享状态的全局变量 。 http.DefaultClient 没有设置超时 , 因此很容易引发 DOS 攻击 , 并造成瓶颈 。 许多包都会修改 http.DefaultClient 和 http.DefaultTransport , 这会导致开发人员需要浪费数天来跟踪错误 。

特别声明:本站内容均来自网友提供或互联网,仅供参考,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。