sort out basic logging

This commit is contained in:
dre 2021-07-08 14:31:22 +08:00
parent 5541785463
commit 504f45524f
2 changed files with 73 additions and 18 deletions

View file

@ -83,12 +83,29 @@ type Server struct {
// Hostname or common name of the server. This is used for absolute redirects.
Hostname string
// Logger enables logging of the gemini server for debugging purposes.
Logger *log.Logger
TLSConfig *tls.Config
Handler Handler // handler to invoke
ReadTimeout time.Duration
MaxOpenConns int
}
func (s *Server) log(v string) {
if s.Logger == nil {
return
}
s.Logger.Println("DEBUG " + v)
}
func (s *Server) logf(format string, v ...interface{}) {
if s.Logger == nil {
return
}
s.log(fmt.Sprintf(format, v...))
}
func (s *Server) ListenAndServe() error {
// outer for loop, if listener closes we will restart it. This may be useful if we switch out
// TLSConfig.
@ -104,7 +121,7 @@ func (s *Server) ListenAndServe() error {
for {
conn, err := listener.Accept()
if err != nil {
log.Printf("server: accept: %s", err)
s.logf("server accept error: %v", err)
break
}
queue <- conn
@ -148,12 +165,14 @@ func (s *Server) handleConnection(conn net.Conn, sem chan struct{}) {
}
s.Handler.ServeGemini(conn, r)
case <-time.After(s.ReadTimeout):
s.logf("server read timeout, request queue length %v/%v", len(sem), s.MaxOpenConns)
WriteHeader(conn, StatusServerUnavailable, "")
}
}
func (s *Server) handleRequestError(conn net.Conn, req request) {
// TODO: log err
s.logf("server error: '%s' %v", strings.TrimSpace(req.rawuri), req.err)
var gmierr *GmiError
if errors.As(req.err, &gmierr) {
WriteHeader(conn, gmierr.Code, gmierr.Error())

68
main.go
View file

@ -11,6 +11,7 @@ import (
"mime"
"os"
"path"
"path/filepath"
"strings"
"time"
@ -30,8 +31,9 @@ const (
)
func main() {
var addr, root, crt, key, host string
var addr, root, crt, key, host, logs string
var maxconns, timeout int
var debug bool
flag.StringVar(&addr, "addr", defaultAddress, "address to listen on. E.g. 127.0.0.1:1965")
flag.IntVar(&maxconns, "max-conns", defaultMaxConns, "maximum number of concurrently open connections")
@ -40,8 +42,39 @@ func main() {
flag.StringVar(&host, "host", defaultHost, "hostname / x509 Common Name when using temporary self-signed certs")
flag.StringVar(&crt, "cert", defaultCertPath, "TLS chain of one or more certificates")
flag.StringVar(&key, "key", defaultKeyPath, "TLS private key")
flag.StringVar(&logs, "logs", "", "directory for file based logging")
flag.BoolVar(&debug, "debug", false, "enable verbose logging of the gemini server")
flag.Parse()
// TODO: rotate on SIGHUP
flogger := log.New(os.Stdout, "", log.LUTC|log.Ldate|log.Ltime)
if logs != "" {
logpath := filepath.Join(logs, "access.log")
accessLog, err := os.OpenFile(logpath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
log.Fatal(err)
}
defer accessLog.Close()
flogger.SetOutput(accessLog)
}
var dlogger *log.Logger
if debug {
dlogger = log.New(os.Stdout, "", log.LUTC|log.Ldate|log.Ltime)
if logs != "" {
logpath := filepath.Join(logs, "debug.log")
debugLog, err := os.OpenFile(logpath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
if err != nil {
log.Fatal(err)
}
defer debugLog.Close()
dlogger.SetOutput(debugLog)
}
}
var err error
var cert tls.Certificate
if crt != "" && key != "" {
@ -65,7 +98,7 @@ func main() {
}
mux := gemini.NewMux()
mux.Use(logger)
mux.Use(logger(flogger))
mux.Handle(gemini.HandlerFunc(fileserver(root)))
server := &gemini.Server{
@ -75,6 +108,7 @@ func main() {
Handler: mux,
MaxOpenConns: maxconns,
ReadTimeout: time.Duration(timeout) * time.Second,
Logger: dlogger,
}
//confirm := make(chan struct{}, 1)
@ -111,23 +145,25 @@ func main() {
*/
}
func logger(next gemini.Handler) gemini.Handler {
fn := func(w io.Writer, r *gemini.Request) {
t := time.Now()
func logger(log *log.Logger) func(next gemini.Handler) gemini.Handler {
return func(next gemini.Handler) gemini.Handler {
fn := func(w io.Writer, r *gemini.Request) {
t := time.Now()
next.ServeGemini(w, r)
next.ServeGemini(w, r)
ip := strings.Split(r.RemoteAddr, ":")[0]
hostname, _ := os.Hostname()
fmt.Printf("%s %s - - [%s] \"%s\" - %v\n",
hostname,
ip,
t.Format("02/Jan/2006:15:04:05 -0700"),
r.URL.Path,
time.Since(t),
)
ip := strings.Split(r.RemoteAddr, ":")[0]
hostname, _ := os.Hostname()
fmt.Printf("%s %s - - [%s] \"%s\" - %v\n",
hostname,
ip,
t.Format("02/Jan/2006:15:04:05 -0700"),
r.URL.Path,
time.Since(t),
)
}
return gemini.HandlerFunc(fn)
}
return gemini.HandlerFunc(fn)
}
func fileserver(root string) func(w io.Writer, r *gemini.Request) {