最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

go - Golang: logs not written to stdout after webserver starts (ListenAndServe) - Stack Overflow

programmeradmin2浏览0评论

I am writing an application in Golang that processes incoming HTTP requests from SNS. The application starts and returns different HTTP errors when I send bad requests, however, none of the requests are being written to stdout and none of my debugging log/fmt.Printf statements are being written to stdout. Below is an excerpt from my code:

func main() {
    // Configure logging
    //log.SetOutput(io.MultiWriter(os.Stdout))
    //log.SetFlags(log.LstdFlags | log.Lshortfile | log.LUTC)

    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }

    // Register handler
    http.HandleFunc("/sns", handleSNS)

    addr := fmt.Sprintf(":%s", port)
    fmt.Printf("Server starting on port %s\n", port)
    os.Stdout.Sync()

    if err := http.ListenAndServe(addr, nil); err != nil {
        fmt.Printf("Failed to start server: %v\n", err)
        os.Stdout.Sync()
        os.Exit(1)
    }
}
func handleSNS(w http.ResponseWriter, r *http.Request) {
    fmt.Println("Received HTTP request at /sns")
    os.Stdout.Sync()
    if r.Method != http.MethodPost {
        fmt.Println(os.Stdout, "Invalid method: %s", r.Method)
        os.Stdout.Sync()
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }
    // Read the raw body for logging
    body, err := io.ReadAll(r.Body)
    if err != nil {
        fmt.Println(os.Stdout, "Error reading request body: %v", err)
        os.Stdout.Sync()
        http.Error(w, "Error reading request", http.StatusBadRequest)
        return
    }
...

The application is running as a container on Kubernetes. I've tried a variety of things, e.g. flushing the logs, switching from log statements to fmt.Println and Printf statements, explicitly writing the os.Stdout, etc. The only log line printed to stdout is the "Server starting on port 8080", then nothing from then on. Anyone know what could be wrong and how to fix it? Thanks, Jeremy

I am writing an application in Golang that processes incoming HTTP requests from SNS. The application starts and returns different HTTP errors when I send bad requests, however, none of the requests are being written to stdout and none of my debugging log/fmt.Printf statements are being written to stdout. Below is an excerpt from my code:

func main() {
    // Configure logging
    //log.SetOutput(io.MultiWriter(os.Stdout))
    //log.SetFlags(log.LstdFlags | log.Lshortfile | log.LUTC)

    port := os.Getenv("PORT")
    if port == "" {
        port = "8080"
    }

    // Register handler
    http.HandleFunc("/sns", handleSNS)

    addr := fmt.Sprintf(":%s", port)
    fmt.Printf("Server starting on port %s\n", port)
    os.Stdout.Sync()

    if err := http.ListenAndServe(addr, nil); err != nil {
        fmt.Printf("Failed to start server: %v\n", err)
        os.Stdout.Sync()
        os.Exit(1)
    }
}
func handleSNS(w http.ResponseWriter, r *http.Request) {
    fmt.Println("Received HTTP request at /sns")
    os.Stdout.Sync()
    if r.Method != http.MethodPost {
        fmt.Println(os.Stdout, "Invalid method: %s", r.Method)
        os.Stdout.Sync()
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }
    // Read the raw body for logging
    body, err := io.ReadAll(r.Body)
    if err != nil {
        fmt.Println(os.Stdout, "Error reading request body: %v", err)
        os.Stdout.Sync()
        http.Error(w, "Error reading request", http.StatusBadRequest)
        return
    }
...

The application is running as a container on Kubernetes. I've tried a variety of things, e.g. flushing the logs, switching from log statements to fmt.Println and Printf statements, explicitly writing the os.Stdout, etc. The only log line printed to stdout is the "Server starting on port 8080", then nothing from then on. Anyone know what could be wrong and how to fix it? Thanks, Jeremy

Share Improve this question asked 2 days ago Jeremy CowanJeremy Cowan 7815 silver badges14 bronze badges 2
  • 1 I can't see any reason for this, can you please change the "Server starting on.." message, rebuild, and check you see the updated message (have had similar issues in the past where I had not noticed the image build was failing so old code was being run). – Brits Commented yesterday
  • Check the return value of os.Stdout.Sync. I'm not sure about it's behaviour outside of Linux, but on linux it shouldn't be necessary. IIRC writing to stdout is blocking - at least in the runtime level, and given handlers can be called concurrently, it's better to let the runtime handle this. Other than that, you'd have to detail how you run your application, and perhaps consider digging deeper: run it through dlv, set a breakpoint on a call to the Println calls and the os.Stdout.Sync calls to see what's going on in the runtime – Elias Van Ootegem Commented 19 hours ago
Add a comment  | 

1 Answer 1

Reset to default 0

I know what is going on here..

The main issue is in how you're trying to write to stdout, especially in the handleSNS function.

You have this small issue:

fmt.Println(os.Stdout, "Invalid method: %s", r.Method)

This is the tricky part - fmt.Println doesn't work like we might think here. It's not like other languages where we can just tell it where to print. When you try to use it like this, it's basically ignoring your attempt to write to stdout.

try fixing with the following code:

func handleSNS(w http.ResponseWriter, r *http.Request) {
    log.Printf("Received HTTP request at /sns")  // Changed this
    
    if r.Method != http.MethodPost {
        log.Printf("Invalid method: %s", r.Method)  // And this
        http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
        return
    }
    
    body, err := io.ReadAll(r.Body)
    if err != nil {
        log.Printf("Error reading request body: %v", err)  // And this
        http.Error(w, "Error reading request", http.StatusBadRequest)
        return
    }
}

log.Printf is made for this kind of stuff - it's like Go's built-in way to handle logs properly, it automatically adds timestamps (which is super helpful for debugging!) and it handles the formatting for you

If you want to make absolutely sure your logs show up right away (sometimes they get stuck in a buffer), you can add this at the start of your main function:

output := bufio.NewWriterSize(os.Stdout, 0)
log.SetOutput(output)

Hope this helps!

发布评论

评论列表(0)

  1. 暂无评论