我应该在生产代码中使用fmt吗?

时间:2016-04-18 17:27:55

标签: logging go production-environment

我看到很多Go代码看起来像这样:

func main() {
    response, _, err := http.Get("http://golang.org/")
    if err != nil {
        fmt.Printf("%s", err)
        os.Exit(1)
    }

    defer response.Body.Close()
    contents, err := ioutil.ReadAll(response.Body)
    if err != nil {
        fmt.Printf("%s", err)
        os.Exit(1)
    }

    fmt.Printf("%s\n", string(contents))
}

我的问题是:

  1. 在制作中,我应该保留这些fmt.Printf声明吗?愚蠢的问题我确定但只是检查

  2. 您为生产代码和开发人员推荐了哪些日志记录选项?

4 个答案:

答案 0 :(得分:0)

认为在某些情况下使用<section style="direction:rtl;"> <div class="container"> <div class="row"> <div class="col-sm-12"> <div class="row"> <div class="col-sm-4 col-sm-push-8 col-md-3 col-md-push-9"><div class="well">Column 1</div></div> <div class="col-sm-4 col-sm-push-0 col-md-3 col-md-push-3"><div class="well">Column 2</div></div> <div class="col-sm-4 col-sm-pull-8 col-md-3 col-md-pull-3"><div class="well">Column 3</div></div> <div class="col-sm-4 col-sm-push-8 col-md-3 col-md-pull-9"><div class="well">Column 4</div></div> <div class="col-sm-4 col-sm-push-0 col-md-3 col-md-push-9"><div class="well">Column 5</div></div> <div class="col-sm-4 col-sm-pull-8 col-md-3 col-md-push-3"><div class="well">Column 6</div></div> <div class="col-sm-4 col-sm-push-8 col-md-3 col-md-pull-3"><div class="well">Column 7</div></div> <div class="col-sm-4 col-sm-pull-0 col-md-3 col-md-pull-9"><div class="well">Column 8</div></div> <div class="col-sm-4 col-sm-pull-8 col-md-3 col-md-push-9"><div class="well">Column 9</div></div> <div class="col-sm-4 col-sm-push-8 col-md-3 col-md-push-3"><div class="well">Column 10</div></div> <div class="col-sm-4 col-sm-pull-0 col-md-3 col-md-pull-3"><div class="well">Column 11</div></div> <div class="col-sm-4 col-sm-pull-8 col-md-3 col-md-pull-9"><div class="well">Column 12</div></div> </div> </div> </div> 是可以接受的。在生产环境中使用不同的日志记录策略会更好。

例如,如果您的应用程序是在后台运行的守护程序,那么除非您不将它们传输到文件中,否则您将错过所有printf

一个好的方法是使用日志轮换(因为你不想拥有令人难以置信的巨大文件)而不是重新发明你自己的logrotate,你可以根据你的需要使用标准软件包或外部软件包。

Golang提供了一个logsyslog子包,它是依靠操作系统syslog进行简单日志记录的最佳解决方案。

答案 1 :(得分:0)

fmt.Printf()适合开始勾画你的程序,但你应该删除它们或用真实的日志记录语句替换。

如果我需要更多标准loglogrus,我已经好运了。

所有日志记录都取决于其他操作相关的问题,因此处理/查看日志的人/事情很重要。

答案 2 :(得分:0)

我认为最好的方法是准备代码,以便在启动go应用程序时使用输入参数轻松从开发环境切换到生产环境。

您可以创建一个variuos级别的日志:

<强>&#34;总是&#34;日志级别

此日志级别始终处于启用状态,提供有关应用程序状态的重要信息(如果需要)。还报告崩溃消息。

<强>&#34;测试&#34;日志级别

当您的代码完成时,此日志级别包含有用的信息,但您必须在代码处于生产状态时检查某些信息不再有用

<强>&#34;调试和#34;日志级别

当您处于开发环境中开发新功能或优化已存在的代码时,此日志级别包含有用信息

在我看来,最好的方法是使用 chan ,它允许你创建一个异步守护进程并在任何你想要的地方记录。

您可以阅读有关陈here的一些信息。

守护进程的一个例子可能是:

func daemonLogging(importantMessage chan error, testingMessage chan error,debugMessage chan error){
    for{

        if globalDebugFlag == true{
            // Log debug message
        }

        if globalTestingMessage == true{
            // Log Testing message
        }

        // Log important message
    }
}

请务必使用go关键字

调用此函数

我认为您使用的 包不重要(如果您没有任何需要),但 决定记录您的消息非常重要

答案 3 :(得分:0)

我对此的看法是,对于相对简单的&#34;类似服务的&#34;解决方案(一个长期运行的程序为用户请求提供服务)这种方法非常正常,前提是您切换到log.Fatal*(),为每个消息输出添加时间戳,或者在一些合理的主管(systemd,{daemon下运行您的服务。 {1}},runit等),它会将您的程序输出转发到适当的系统日志接收器中。

记录方法也很大程度上取决于程序的性质。 比方说,对于执行一次性操作的命令行应用程序(curlwget是这样一个程序的一个很好的例子 - 在您的代码示例的精神中)记录到它们的标准错误流并退出是唯一理智的运作模式。守护进程(服务)预计会无人值守,因此你必须确保他们的日志被发送和存储在某个地方,并加上时间戳。

一个小注意事项:一个表现良好的程序应该将错误消息输出到其标准错误流,所以如果你不想使用log.Fatal*()进行某些重复,至少要做{{1 }})。