Browse Source

Better logger, optimisation, wrapper

Vova Tkach 6 years ago
parent
commit
e9893f15c9
7 changed files with 156 additions and 49 deletions
  1. 1 1
      consts/consts.go
  2. 22 21
      engine/engine.go
  3. 37 0
      engine/wrapper/wrapper.go
  4. 3 3
      logger/handler.go
  5. 82 10
      logger/logger.go
  6. 10 13
      main.go
  7. 1 1
      utils/utils.go

+ 1 - 1
consts/consts.go

@@ -1,6 +1,6 @@
 package consts
 
-const Debug = !false
+const Debug = true
 const ServerVersion = "1.0.1"
 const AssetsVersion = "1"
 const AssetsPath = "assets"

+ 22 - 21
engine/engine.go

@@ -4,38 +4,39 @@ import (
 	"fmt"
 	"net/http"
 
+	"golang-fave/engine/wrapper"
+	"golang-fave/logger"
+
 	"github.com/vladimirok5959/golang-server-sessions/session"
 )
 
 type Engine struct {
-	w http.ResponseWriter
-	r *http.Request
-	s *session.Session
-
-	host string
-	port string
-
-	dConfig   string
-	dHtdocs   string
-	dLogs     string
-	dTemplate string
-	dTmp      string
+	Wrap *wrapper.Wrapper
+	// Database
+	// Actions
+	// Front-end or Back-end
 }
 
-func New(w http.ResponseWriter, r *http.Request, s *session.Session, host, port, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp string) *Engine {
-	return &Engine{w, r, s, host, port, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp}
+func Response(l *logger.Logger, w http.ResponseWriter, r *http.Request, s *session.Session, host, port, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp string) bool {
+	wrap := wrapper.New(l, w, r, s, host, port, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp)
+	eng := &Engine{Wrap: wrap}
+
+	return eng.Process()
 }
 
-func (this *Engine) Response() bool {
-	if this.r.URL.Path == "/" {
-		this.w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
-		this.w.Header().Set("Content-Type", "text/html")
+func (this *Engine) Process() bool {
+	if this.Wrap.R.URL.Path == "/" {
+		this.Wrap.W.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
+		this.Wrap.W.Header().Set("Content-Type", "text/html")
+
+		counter := this.Wrap.S.GetInt("counter", 0)
+		// this.Wrap.LogAccess(fmt.Sprintf("Counter value was: %d", counter))
 
-		counter := this.s.GetInt("counter", 0)
-		this.w.Write([]byte(`Logic -> (` + fmt.Sprintf("%d", counter) + `)`))
+		this.Wrap.W.Write([]byte(`Logic -> (` + fmt.Sprintf("%d", counter) + `)`))
 
 		counter++
-		this.s.SetInt("counter", counter)
+		this.Wrap.S.SetInt("counter", counter)
+		// this.Wrap.LogAccess(fmt.Sprintf("Counter value now: %d", counter))
 
 		return true
 	}

+ 37 - 0
engine/wrapper/wrapper.go

@@ -0,0 +1,37 @@
+package wrapper
+
+import (
+	"net/http"
+
+	"golang-fave/logger"
+
+	"github.com/vladimirok5959/golang-server-sessions/session"
+)
+
+type Wrapper struct {
+	l *logger.Logger
+	W http.ResponseWriter
+	R *http.Request
+	S *session.Session
+
+	Host string
+	Port string
+
+	DConfig   string
+	DHtdocs   string
+	DLogs     string
+	DTemplate string
+	DTmp      string
+}
+
+func New(l *logger.Logger, w http.ResponseWriter, r *http.Request, s *session.Session, host, port, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp string) *Wrapper {
+	return &Wrapper{l, w, r, s, host, port, dirConfig, dirHtdocs, dirLogs, dirTemplate, dirTmp}
+}
+
+func (this *Wrapper) LogAccess(msg string) {
+	this.l.Log(msg, this.R, false)
+}
+
+func (this *Wrapper) LogError(msg string) {
+	this.l.Log(msg, this.R, true)
+}

+ 3 - 3
logger/handler.go

@@ -12,11 +12,11 @@ import (
 type handler struct {
 	h http.Handler
 	w io.Writer
-	c chan string
+	c chan logMsg
 }
 
 func (this handler) log(w *writer, r *http.Request) {
-	str := fmt.Sprint(strings.Join([]string{
+	msg := fmt.Sprint(strings.Join([]string{
 		r.Host,
 		r.RemoteAddr,
 		"-",
@@ -32,7 +32,7 @@ func (this handler) log(w *writer, r *http.Request) {
 	// Do not wait
 	go func() {
 		select {
-		case this.c <- str:
+		case this.c <- logMsg{r.Host, msg, w.status >= 400}:
 			return
 		case <-time.After(1 * time.Second):
 			fmt.Println("Logger error, log channel is overflowed (2)")

+ 82 - 10
logger/logger.go

@@ -5,23 +5,90 @@ import (
 	"net/http"
 	"os"
 	"time"
+
+	"golang-fave/consts"
+	"golang-fave/utils"
 )
 
+type logMsg struct {
+	host    string
+	message string
+	isError bool
+}
+
 type Logger struct {
 	wwwDir string
-	cdata  chan string
+	cdata  chan logMsg
 	cclose chan bool
 }
 
-func (this *Logger) write(str string) {
-	// TODO: write to console or to file
-	// If www and host home dir are exists
-	fmt.Fprintln(os.Stdout, str)
+func (this *Logger) console(msg logMsg) {
+	if consts.Debug {
+		if !msg.isError {
+			fmt.Fprintln(os.Stdout, "[ACCESS] "+msg.message)
+		} else {
+			fmt.Fprintln(os.Stdout, "[ERROR] "+msg.message)
+		}
+		return
+	}
+
+	if !msg.isError {
+		fmt.Fprintln(os.Stdout, msg.message)
+	} else {
+		fmt.Fprintln(os.Stderr, msg.message)
+	}
+}
+
+func (this *Logger) write(msg logMsg) {
+	// Ignore file if debug
+	if consts.Debug {
+		this.console(msg)
+		return
+	}
+
+	// Ignore file if host not set
+	if msg.host == "" {
+		this.console(msg)
+		return
+	}
+
+	// Ignore file if www dir is not exists
+	if !utils.IsDirExists(this.wwwDir) {
+		this.console(msg)
+		return
+	}
+
+	// Extract host
+	host, _ := utils.ExtractHostPort(msg.host, false)
+	logs_dir := this.wwwDir + string(os.PathSeparator) + host + string(os.PathSeparator) + "logs"
+
+	// Ignore file if logs dir is not exists
+	if !utils.IsDirExists(logs_dir) {
+		this.console(msg)
+		return
+	}
+
+	// Detect which log file
+	log_file := logs_dir + string(os.PathSeparator) + "access.log"
+	if msg.isError {
+		log_file = logs_dir + string(os.PathSeparator) + "error.log"
+	}
+
+	// Try write to file
+	f, err := os.OpenFile(log_file, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
+	if err == nil {
+		defer f.Close()
+		fmt.Fprintln(f, msg.message)
+		return
+	}
+
+	// By default
+	this.console(msg)
 }
 
 func New() *Logger {
 	// Logs channel
-	cdata := make(chan string)
+	cdata := make(chan logMsg)
 
 	// Close channel
 	cclose := make(chan bool)
@@ -33,8 +100,8 @@ func New() *Logger {
 	go func() {
 		for {
 			select {
-			case str := <-cdata:
-				lg.write(str)
+			case msg := <-cdata:
+				lg.write(msg)
 			case <-cclose:
 				cclose <- true
 				return
@@ -45,11 +112,16 @@ func New() *Logger {
 	return &lg
 }
 
-func (this *Logger) Log(str string) {
+func (this *Logger) Log(msg string, r *http.Request, isError bool) {
+	var host string = ""
+	if r != nil {
+		host = r.Host
+	}
+
 	// Do not wait
 	go func() {
 		select {
-		case this.cdata <- str:
+		case this.cdata <- logMsg{host, msg, isError}:
 			return
 		case <-time.After(1 * time.Second):
 			fmt.Println("Logger error, log channel is overflowed (1)")

+ 10 - 13
main.go

@@ -37,9 +37,9 @@ func main() {
 
 	// Check www dir
 	ParamWwwDir = utils.FixPath(ParamWwwDir)
-	if !utils.IsHostDirExists(ParamWwwDir) {
-		lg.Log("Virtual hosts directory is not exists")
-		lg.Log("Example: ./fave -host 127.0.0.1 -port 80 -dir ./hosts")
+	if !utils.IsDirExists(ParamWwwDir) {
+		lg.Log("Virtual hosts directory is not exists", nil, true)
+		lg.Log("Example: ./fave -host 127.0.0.1 -port 80 -dir ./hosts", nil, true)
 		return
 	}
 
@@ -73,7 +73,7 @@ func main() {
 		// Host and port
 		host, port := utils.ExtractHostPort(r.Host, false)
 		vhost_dir := ParamWwwDir + string(os.PathSeparator) + host
-		if !utils.IsHostDirExists(vhost_dir) {
+		if !utils.IsDirExists(vhost_dir) {
 			vhost_dir = ParamWwwDir + string(os.PathSeparator) + "localhost"
 		}
 
@@ -83,23 +83,23 @@ func main() {
 		vhost_dir_logs := vhost_dir + string(os.PathSeparator) + "logs"
 		vhost_dir_template := vhost_dir + string(os.PathSeparator) + "template"
 		vhost_dir_tmp := vhost_dir + string(os.PathSeparator) + "tmp"
-		if !utils.IsHostDirExists(vhost_dir_config) {
+		if !utils.IsDirExists(vhost_dir_config) {
 			utils.SystemErrorPageEngine(w, errors.New("Folder "+vhost_dir_config+" is not found"))
 			return
 		}
-		if !utils.IsHostDirExists(vhost_dir_htdocs) {
+		if !utils.IsDirExists(vhost_dir_htdocs) {
 			utils.SystemErrorPageEngine(w, errors.New("Folder "+vhost_dir_htdocs+" is not found"))
 			return
 		}
-		if !utils.IsHostDirExists(vhost_dir_logs) {
+		if !utils.IsDirExists(vhost_dir_logs) {
 			utils.SystemErrorPageEngine(w, errors.New("Folder "+vhost_dir_logs+" is not found"))
 			return
 		}
-		if !utils.IsHostDirExists(vhost_dir_template) {
+		if !utils.IsDirExists(vhost_dir_template) {
 			utils.SystemErrorPageEngine(w, errors.New("Folder "+vhost_dir_template+" is not found"))
 			return
 		}
-		if !utils.IsHostDirExists(vhost_dir_tmp) {
+		if !utils.IsDirExists(vhost_dir_tmp) {
 			utils.SystemErrorPageEngine(w, errors.New("Folder "+vhost_dir_tmp+" is not found"))
 			return
 		}
@@ -114,7 +114,7 @@ func main() {
 		defer sess.Close()
 
 		// Logic
-		if engine.New(w, r, sess, host, port, vhost_dir_config, vhost_dir_htdocs, vhost_dir_logs, vhost_dir_template, vhost_dir_tmp).Response() {
+		if engine.Response(lg, w, r, sess, host, port, vhost_dir_config, vhost_dir_htdocs, vhost_dir_logs, vhost_dir_template, vhost_dir_tmp) {
 			return
 		}
 
@@ -122,9 +122,6 @@ func main() {
 		utils.SystemErrorPage404(w)
 	})
 
-	// Close logger
-	//lg.Close()
-
 	// TODO: call it in background time by time
 	// Delete expired session files
 	// session.Clean("./tmp")

+ 1 - 1
utils/utils.go

@@ -30,7 +30,7 @@ func IsDir(filename string) bool {
 	return false
 }
 
-func IsHostDirExists(path string) bool {
+func IsDirExists(path string) bool {
 	if IsFileExists(path) && IsDir(path) {
 		return true
 	}