kratos源码分析系列(4)

2023-03-14 20:44:45 浏览数 (2)

接着按目录分析源码:

5,encoding

支持的格式有form、json、proto、xml、yaml,使用的包有

https://github.com/go-playground/form、google.golang.org/protobuf/encoding/protojson,实现了encoding/encoding.go的codec接口

代码语言:javascript复制
type Codec interface {
  // Marshal returns the wire format of v.
  Marshal(v interface{}) ([]byte, error)
  // Unmarshal parses the wire format into v.
  Unmarshal(data []byte, v interface{}) error
  // Name returns the name of the Codec implementation. The returned string
  // will be used as part of content type in transmission.  The result must be
  // static; the result cannot change between calls.
  Name() string
}

可以根据需要注册编解码方式

代码语言:javascript复制
func RegisterCodec(codec Codec) {

6,errors 使用了errors/errors.proto自定义proto可选项

代码语言:javascript复制
extend google.protobuf.EnumOptions {
  int32 default_code = 1108;
}

extend google.protobuf.EnumValueOptions {
  int32 code = 1109;
}

并提供了相应的包裹和解包裹方法errors/wrap.go

代码语言:javascript复制
func As(err error, target interface{}) bool { return stderrors.As(err, target) }
    func Unwrap(err error) error {
  return stderrors.Unwrap(err)
}
func Is(err, target error) bool { return stderrors.Is(err, target) }

6,internal

提供了一系列内部需要的工具方法,比如context

代码语言:javascript复制
func Merge(parent1, parent2 context.Context) (context.Context, context.CancelFunc) {
    func (mc *mergeCtx) Err() error {

endpoint

代码语言:javascript复制
func ParseEndpoint(endpoints []string, scheme string) (string, error) {
func Scheme(scheme string, isSecure bool) string {

group

代码语言:javascript复制
func (g *Group) Get(key string) interface{} {
func (g *Group) Reset(new func() interface{}) {
func (g *Group) Clear() {

host

代码语言:javascript复制
func ExtractHostPort(addr string) (host string, port uint64, err error) {
func Port(lis net.Listener) (int, bool) {
func Extract(hostPort string, lis net.Listener) (string, error) {

httputil

代码语言:javascript复制
func ContentSubtype(contentType string) string {
func ContentType(subtype string) string {

matcher

代码语言:javascript复制
func (m *matcher) Add(selector string, ms ...middleware.Middleware) {
func (m *matcher) Match(operation string) []middleware.Middleware {

testdata

7,log

定义了写日志时候的过滤,指定日志输出方式等辅助方法

filter

代码语言:javascript复制
func FilterFunc(f func(level Level, keyvals ...interface{}) bool) FilterOption {
func (f *Filter) Log(level Level, keyvals ...interface{}) error {
  if level < f.level {
    return nil
  }

global

代码语言:javascript复制
func init() {
  global.SetLogger(DefaultLogger)
}

helper_writter

代码语言:javascript复制
func (ww *writerWrapper) Write(p []byte) (int, error) {
  ww.helper.Log(ww.level, ww.helper.msgKey, string(p))
  return 0, nil
}

helper

代码语言:javascript复制
func (h *Helper) WithContext(ctx context.Context) *Helper {

level

代码语言:javascript复制
func ParseLevel(s string) Level {

log

代码语言:javascript复制
func (c *logger) Log(level Level, keyvals ...interface{}) error {

std

代码语言:javascript复制
func (l *stdLogger) Log(level Level, keyvals ...interface{}) error {

value

代码语言:javascript复制
func Caller(depth int) Valuer {

Logger统一了日志的接入方式,Helper接口统一的日志库的调用方式。Kratos的日志库主要有如下特性:

Logger用于对接各种日志库或日志平台,可以用现成的或者自己实现

Helper是在您的项目代码中实际需要调用的,用于在业务代码里打日志

Filter用于对输出日志进行过滤或魔改(通常用于日志脱敏)

Valuer用于绑定一些全局的固定值或动态值(比如时间戳、traceID或者实例id之类的东西)到输出日志中

8,metadata

解决了http和grpc之间header的传递问题

代码语言:javascript复制
  func FromServerContext(ctx context.Context) (Metadata, bool) {
  func AppendToClientContext(ctx context.Context, kv ...string) context.Context {
    _, file, line, _ := runtime.Caller(depth)

默认格式规范

x-md-global-xxx,全局传递,例如 mirror/color/criticality

x-md-local-xxx,局部传递,例如 caller

也可以在 middleware/metadata 定制自己的 key prefix,配置固定的元信息传递

9,metrics

代码语言:javascript复制
type Counter interface {
  With(lvs ...string) Counter
  Inc()
  Add(delta float64)
}
代码语言:javascript复制
// Gauge is metrics gauge.
type Gauge interface {
  With(lvs ...string) Gauge
  Set(value float64)
  Add(delta float64)
  Sub(delta float64)
}
代码语言:javascript复制
// Observer is metrics observer.
type Observer interface {
  With(lvs ...string) Observer
  Observe(float64)
}

0 人点赞