为了账号安全,请及时绑定邮箱和手机立即绑定

Golang 包中正确的日志记录实现

Golang 包中正确的日志记录实现

Go
慕桂英546537 2022-06-13 16:55:06
我有一个小的 Golang包,它可以做一些工作。这项工作假设可能会产生大量错误,这是可以的。目前所有错误都被忽略。是的,它可能看起来很奇怪,但请访问链接并检查包的主要用途。我想扩展包的功能并提供在运行时查看错误的能力。但是由于缺乏软件设计技能,我有一些问题没有答案。起初,我想使用现有的日志记录(zerolog、zap 或其他任何东西)在包内实现日志记录。但是,包的用户可以吗?因为他们可能想使用其他日志记录包并想修改输出格式。也许有可能为用户提供一种注入它自己的日志记录的方法?我想实现提供易于配置的日志记录方式的能力,可以根据用户的需求打开或关闭。
查看完整描述

2 回答

?
眼眸繁星

TA贡献1873条经验 获得超9个赞

有些 go lib 使用这样的日志记录


在你的包中确定一个记录器接口


type Yourlogging interface{

      Errorf(...)

      Warningf(...)

      Infof(...)

      Debugf(...)

}

并为此接口定义一个变量


  var mylogger Yourlogging

  func SetLogger(l yourlogging)error{

       mylogger = l

  }

在您的函数中,您可以调用它们进行日志记录


  mylogger.Infof(..)


  mylogger.Errorf(...)

你不需要实现接口,但是你可以使用实现这个接口的他们


 for example:

     SetLogger(os.Stdout)    //logging output to stdout

     SetLogger(logrus.New()) // logging output to logrus  (github.com/sirupsen/logrus)

  

查看完整回答
反对 回复 2022-06-13
?
MM们

TA贡献1886条经验 获得超2个赞

在 Go 中,您会看到一些库实现了日志接口,就像其他答案所建议的那样。但是,例如,如果您以不同的方式构建应用程序,则可以完全避免您的包需要记录。


例如,在您链接的示例应用程序中,您的主应用程序运行时调用idleexacts.Run(),它会启动此函数。


// startLoop starts workload using passed settings and database connection.

func startLoop(ctx context.Context, log log.Logger, pool db.DB, tables []string, jobs uint16, minTime, maxTime time.Duration) error {

    rand.Seed(time.Now().UnixNano())


    // Increment maxTime up to 1 due to rand.Int63n() never return max value.

    maxTime++


    // While running, keep required number of workers using channel.

    // Run new workers only until there is any free slot.

    guard := make(chan struct{}, jobs)

    for {

        select {

        // Run workers only when it's possible to write into channel (channel is limited by number of jobs).

        case guard <- struct{}{}:

            go func() {

                table := selectRandomTable(tables)

                naptime := time.Duration(rand.Int63n(maxTime.Nanoseconds()-minTime.Nanoseconds()) + minTime.Nanoseconds())


                err := startSingleIdleXact(ctx, pool, table, naptime)

                if err != nil {

                    log.Warnf("start idle xact failed: %s", err)

                }


                // When worker finishes, read from the channel to allow starting another worker.

                <-guard

            }()

        case <-ctx.Done():


            return nil

        }

    }

}

这里的问题是你的逻辑的所有编排都发生在你的包内部。相反,这个循环应该在你的主应用程序中运行,并且这个包应该为用户提供简单的操作,例如selectRandomTable()or createTempTable()。


如果代码编排在您的主应用程序中,并且包仅提供简单的操作。作为函数调用的一部分,将错误返回给用户会容易得多。


它还可以使您的包更容易被其他人重用,因为它们具有简单的操作并且可以让用户以超出您预期的其他方式使用它们。


查看完整回答
反对 回复 2022-06-13
  • 2 回答
  • 0 关注
  • 122 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信