Reputation: 26084
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
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
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
Reputation: 49265
You can't print a log message after ListenAndServe
since it blocks and never returns, so basically you have two main options:
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.
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
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