当执行”log.Fatal()”时如何发送HTTP请求?

huangapple go评论79阅读模式
英文:

How to send HTTP request when "log.Fatal()" is executed?

问题

我想在每个日志语句中调用"log.Fatal()"时,将日志发送到我的HTTP服务器,而无需任何额外的代码。改变/覆盖log.Info()log.Fatal()等的默认行为将是很棒的。

英文:

I want to send logs to my HTTP server when the "log.Fatal()" is called without any extra code for every log statement. Changing/overwriting the default behaviour of log.Info(), log.Fatal(), etc. would be fantastic.

答案1

得分: 3

你可以为内置的log创建一个包装模块。

yourproject/log/log.go

package log
import goLog "log"
func Fatal(v ...interface{}) {
   goLog.Fatal(v...)
   // 发送请求 ...
   // reqQueue <- 一些参数
}

在你的项目中用包装模块替换log模块

// import "log"
import "yourproject/log"

func Foo() {
    log.Fatal(err)
}
英文:

You can create a wrapper module for builtin log

yourproject/log/log.go

package log
import goLog &quot;log&quot;
func Fatal(v ...interface{}) {
   goLog.Fatal(v...)
   // send request ...
   // reqQueue &lt;- some args
}

replace log module with the wrapper in your project

// import &quot;log&quot;
import &quot;yourproject/log&quot;

func Foo() {
    log.Fatal(err)
}

答案2

得分: 1

尝试创建一个包装标准Logger类型的类型,但具有您所需的增强功能。然后,通过创建一个名为"log"的实例来包装默认的记录器,您可以继续以最小的更改在代码中使用记录功能(因为它将具有与日志包相同的名称,并保留*所有方法)。

package main

import _log "log"

type WrappedLogger struct {
    // 这个字段没有名称,所以我们保留了所有Logger的方法
    *_log.Logger
}

// 在这里我们重写了log.Fatal的行为
func (l *WrappedLogger) Fatal(v ...interface{}) {
    l.Println("doing the HTTP request")
    /// 做HTTP请求

    // 现在调用底层记录器的原始Fatal方法
    l.Logger.Fatal(v...)
}

// 包装默认记录器,但添加了我们的新方法。
var log = WrappedLogger{_log.Default()}

func main() {
    // 注意我们仍然可以使用Println
    log.Println("hello")
    // 但现在Fatal执行特殊行为
    log.Fatal("fatal log")
}

*唯一需要注意的是,我们用一个记录实例替换了典型的记录。在很多方面,它的行为方式相同,因为日志包中的大多数函数都被设置为方便地转发到默认的Logger实例。

然而,这意味着我们的新log将无法访问日志包中的“真实”函数,例如log.New。为此,您需要引用原始包的别名。

// 想要创建一个新的记录器?
_log.New(out, prefix, flag)
英文:

Try creating a type that wraps the standard Logger type, but with your desired enhancement. Then by creating an instance of it called "log" which wraps the default logger, you can continue to use logging in your code in the same way with minimal changes required (since it will have the same name as the log package, and retain *all of the methods).

package main

import _log &quot;log&quot;

type WrappedLogger struct {
    // This field has no name, so we retain all the Logger methods
    *_log.Logger
}

// here we override the behaviour of log.Fatal
func (l *WrappedLogger) Fatal(v ...interface{}) {
    l.Println(&quot;doing the HTTP request&quot;)
    /// do HTTP request

    // now call the original Fatal method from the underlying logger
    l.Logger.Fatal(v...)
}

// wrapping the default logger, but adding our new method.
var log = WrappedLogger{_log.Default()}

func main() {
    // notice we can still use Println
    log.Println(&quot;hello&quot;)
    // but now Fatal does the special behaviour
    log.Fatal(&quot;fatal log&quot;)
}

*The only gotcha here is that we've replaced the typical log package with a log instance. In many ways, it behaves the same, since most of the functions in the log package are set up as forwards to the default Logger instance for convenience.

However, this means that our new log won't have access to the "true" functions from the log package, such as log.New. For that, you will need to reference the alias to the original package.

// want to create a new logger?
_log.New(out, prefix, flag)

huangapple
  • 本文由 发表于 2021年10月8日 20:06:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/69495594.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定