Go web server shuts down

I am looking for some tip how to narrow down the search for why my go server stops running after a short period.

http://94.237.92.101:5050

My Go code is simple. No SQL involved. Only html templates.

package main

import (
	"fmt"
	"html/template"
	"net/http"
	"strings"
)

func main() {
	http.HandleFunc("/", page)
	http.ListenAndServe(":5050", nil)
}

var tpl *template.Template

func init() {
	tpl = template.Must(template.ParseGlob("public/templates/*.html"))
	http.Handle("/img/", http.StripPrefix("/img/", http.FileServer(http.Dir("./public/img"))))
	http.Handle("/css/", http.StripPrefix("/css/", http.FileServer(http.Dir("./public/css"))))
	http.Handle("/icn/", http.StripPrefix("/icn/", http.FileServer(http.Dir("./public/icn"))))
	http.Handle("/js/", http.StripPrefix("/js/", http.FileServer(http.Dir("./public/js"))))
}

func page(w http.ResponseWriter, r *http.Request) {
	path := strings.Trim(r.URL.Path, "/")

	fmt.Println(path)
	switch path {
	case "favicon.ico":
		http.ServeFile(w, r, "/static/favicon.ico")
	case "norec":
		tpl.ExecuteTemplate(w, "norec.html", "")
	default:
		tpl.ExecuteTemplate(w, "home.html", "")
	}
}

https://play.golang.org/p/sFs4CqZ3Olt

Any clue to find the cause? HTML, CSS and Javascript validated without error.

Does it just exit or do you get a panic or something?

You really should change this.

err := ListenAndServe(":5050", nil)
fmt.Println("%v", err)

(Or whatever else you use for logging)

That way you will have something in your logs.

http.ListenAndServs return value is guaranteed to never be nil, so if it returns, there was an error which you ignore.

If you really do not get such an error logged, then problems are more deep and the process is killed from the outside.

From the server terminal:

Terminated
Command failed with exit status 36608

I get:

undefined: ListenAndServe

solution?

Reading error and code… I forgot to qualify the call, it is http.ListenAndServe of course…

Thanks, but should there not be an if statement also? Or is it not needed? Like:

err := http.ListenAndServe(":5050", nil)
if err != nil {
	fmt.Println("%v", err)
}

As I said, http.ListenAndServe will never return nil.

I have read at several Places that it’s a good idea do place the ListenAndSave in a log.Fatal like

log.Fatal(http.ListenAndServe( “:8080” , nil))

like noted here

As I said, whatever OP uses for logging

The Terminal does not receive any message from this. The server just shuts down silently.

There are other Go Web servers on this server that runs without any problem. Any Javascript that can cause this?

Any further tip?

I’m not sure how you manage your services. But I really don’t believe that it silently exits. And if it does, you need to check for its exit code, perhaps it gets killed by the system via a signal?

Have you checked systems log if OOM killer strikes?

Try one of the top answers “Finding which process was killed by Linux OOM killer - Stack Overflow” https://stackoverflow.com/questions/624857/finding-which-process-was-killed-by-linux-oom-killer

Debian 10 managed by Webmin. The var/log/message contained nothing but normal messages: rsyslogd was HUPed and var/log/stderr is empty.

There is no other process but http.Server running and it is terminated repeatedly by some reason. Either fmt.Println(err) or log.Fatal is reporting any issues. The memory used does not exceed 30 percent.

HTML, CSS and Javascript is validated. And other Go servers on the same server runs perfect on other ports.

I have activated the Firewall, but so far no difference.

Any clue how to find the cause?

I don’t know webmin, but fmt.Println prints to stdout. Not sure what webmin does with what happens on stdout.

Make sure to use whatever logging mechanism usually works for you.

Also make sure that all your endpoints properly log.

Extensive logging is probably the only thing that can help you debugging this.

Also, your service manager should be either able to recognize failure and restart your service, or if it can’t, then it should be replaced. Systemd is pretty good at just doing the right thing.

And again, when your service exits, what exit code does it have?

Terminated
Command failed with exit status 36608

https://play.golang.org/p/vVc3lHSBECg

How do I get this log to print to var/log/stderr ?

log.Fatal(http.ListenAndServe( *“:8080”* , nil))

That is a garbage value. Exit codes on linux are only 8 bit…

If though I look at its individual bytes, then we have 143 0.

If we assume that we can assume the 0 byte, we have an exitcode of 143, which on linux usually means "shut down by SIGTERM".

The default that happens when you use kill $pid on a terminal. Now you need to find out what sends the SIGTERM and why.

Not sure what exactly you mean by that. But if its a file, then open it and write your logs to it. How to do that exactly depends on the logging library you use.

log.Fatal will always log to the processes stderr/fd:2 and then exit the program.

Systemd as well as docker usually take stdout and stderr of a program and write them into their logs, which you can then browse by service/container.

I have no clue how your webmin deals with such stuff.

1 Like

And how do I read this log? var/log/stderr is empty

Again, I have no clue what webmin does. You need to figure out on your own, if it does persist the processes stdout and stderr somewhere.

It is a Debian thing.

  1. First I created a main.exe
    https://play.golang.org/p/29fIe4uHvRi

  2. Then redirected to the var/log/messages in the terminal
    ./main 2>> /var/log/messages

  3. Last I executed the main
    cd /logtest ./main

Aug 18 00:00:05 …rsyslogd was HUPed
Message

The question is how to do #2 (redirect to var/log/messages) from within Go?

Or even better redirect to stderr?