Héctor
Héctor

Reputation: 26084

Log when server is started

Is there any way to print something when the http server starts? For instance "Server is started at port 8080"

In Node (using Express), it would be like:

app.listen(8080, function() { console.log('Server started at port 8080') });

This is my code:

func main() {
    http.HandleFunc("/", MyHandler)
    http.ListenAndServe(":8080", nil)
}

Thanks.

Upvotes: 18

Views: 12852

Answers (4)

LionKing
LionKing

Reputation: 723

Or to run log command in a goroutine:

    errStart := false
    go func() {
        time.Sleep(time.Second * 3)
        if !errStart {
            log.Info("Server is started at port 8080")
        }
    }()
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        errStart = true
        log.Error(...)
    }

Upvotes: -1

Grokify
Grokify

Reputation: 16354

To run ListenAndServe in a goroutine as mentioned by Not_a_Golfer, you can use an unbuffered, blocking channel to run it in a goroutine and also keep the server alive.

The following example creates a channel called done where <-done will keep the server alive as it waits for the goroutine to finish, which it won't in this case. Typically, the goroutine will tell the main function it is finished by executing done <- true.

package main

import (
    "log"
    "net/http"
)

func MyHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello World"))
}

func main() {
    port := "8080"

    http.HandleFunc("/", MyHandler)

    done := make(chan bool)
    go http.ListenAndServe(":"+port, nil)
    log.Printf("Server started at port %v", port)
    <-done
}

Here's a larger example that has the server verify it is operational, using Listen and Serve separately. The nice thing about doing it this way is you can capture an incorrect port easily.

package main

import (
    "log"
    "net"
    "net/http"
    "os"
)

func MyHandler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("Hello World"))
}

func main() {
    port := "8080"

    http.HandleFunc("/", MyHandler)

    listener, err := net.Listen("tcp", ":"+port)
    if err != nil {
        log.Fatal(err)
    }

    done := make(chan bool)
    go http.Serve(listener, nil)

    // Log server started
    log.Printf("Server started at port %v", port)

    // Attempt to connect
    log.Printf("Fetching...")
    res, err := http.Get("http://" + listener.Addr().String())
    log.Printf("Received: %v, %v", res, err)
    if err != nil {
        log.Fatal(err)
    }
    res.Write(os.Stdout)

    <-done
}

Upvotes: 8

Not_a_Golfer
Not_a_Golfer

Reputation: 49265

You can't print a log message after ListenAndServe since it blocks and never returns, so basically you have two main options:

  1. Print "Starting server on port...." and that's it - BUT if ListenAndServe could not start it returns an error, so unless there's some error or panic printed because of that, you can assume the server started.

  2. Call ListenAndServe in a separate goroutine, and make sure there was no error returned and print "Server started..." etc.

I personally prefer the first approach.

Upvotes: 10

lnmx
lnmx

Reputation: 11164

Use Go's log package:

package main

import (
    "net/http"
    "log"
)

func main() {
    addr := ":8080"
    http.HandleFunc("/", MyHandler)
    log.Println("listen on", addr)
    log.Fatal( http.ListenAndServe(addr, nil) )
}

http.ListenAndServe opens the server port, and blocks forever waiting for clients. If it fails to open the port, the log.Fatal call will report the problem and exit the program.

Upvotes: 18

Related Questions