1
0
Fork 0

랜더러 / 로거 정리

릴리즈 모드일때 랜더링안되는거 수정필요
This commit is contained in:
tom.cat 2016-03-11 19:14:53 +09:00
parent 97b2901e7d
commit 75234ebd31
4 changed files with 115 additions and 72 deletions

40
main.go
View File

@ -15,41 +15,36 @@
package main package main
import ( import (
"github.com/gin-gonic/gin" "flag"
"github.com/Sirupsen/logrus" "net/http"
"runtime" "runtime"
"time" "time"
"flag"
"amuz.es/go/mnemonics/route" "amuz.es/go/mnemonics/route"
"amuz.es/go/mnemonics/util" "amuz.es/go/mnemonics/util"
"net/http" "github.com/gin-gonic/gin"
"github.com/flosch/pongo2"
"os"
) )
var argIp = flag.String("listen_ip", "", "IP to listen on, defaults to all IPs") var argIp = flag.String("listen_ip", "", "IP to listen on, defaults to all IPs")
var argPort = flag.Int("port", 8080, "port to listen") var argPort = flag.Int("port", 8080, "port to listen")
var maxProcs = flag.Int("max_procs", 0, "max number of CPUs that can be used simultaneously. Less than 1 for default (number of cores).") var maxProcs = flag.Int("max_procs", 0, "max number of CPUs that can be used simultaneously. Less than 1 for default (number of cores).")
var logger = logrus.New()
func main() { func main() {
flag.Parse() flag.Parse()
setMaxProcs() setMaxProcs()
util.InitLogger()
gin.SetMode(gin.ReleaseMode)
r := gin.New() r := gin.New()
// middleware settings
r.Use(util.Ginrus(time.RFC3339, true))
r.Use(util.Ginrus(logrus.StandardLogger(), time.RFC3339, true))
r.Use(gin.Recovery()) r.Use(gin.Recovery())
// not found handler
r.NoRoute(func(c *gin.Context) { r.NoRoute(func(c *gin.Context) {
c.HTML(http.StatusOK, "page_404.html", pongo2.Context{}) c.HTML(http.StatusOK, "page_404.html", util.Context{})
}) })
logger.Level = logrus.ErrorLevel
logger.Out=os.Stderr
r.Use(util.Ginrus(logger, time.RFC3339, false))
r.StaticFS("/static", route.Static("")) r.StaticFS("/static", route.Static(""))
r.GET("/api", route.Api) r.GET("/api", route.Api)
@ -59,12 +54,15 @@ func main() {
c.String(200, "OK! - mnemonics services are fully operational!") c.String(200, "OK! - mnemonics services are fully operational!")
}) })
// Use pongo2gin.Default() for default options or pongo2gin.New() if gin.IsDebugging() {
// if you need to use custom RenderOptions. r.HTMLRender = util.TemplateSourceDebug("asset/template")
r.HTMLRender = util.Default() } else {
r.HTMLRender = util.TemplateSourceRelease("")
}
r.GET("/", route.Index) r.GET("/", route.Index)
logger.Error("bootstrapped application") util.Log().Error("bootstrapped application")
r.Run() // listen and server on 0.0.0.0:8080 r.Run() // listen and server on 0.0.0.0:8080
} }
@ -83,6 +81,6 @@ func setMaxProcs() {
// Check if the setting was successful. // Check if the setting was successful.
actualNumProcs := runtime.GOMAXPROCS(0) actualNumProcs := runtime.GOMAXPROCS(0)
if actualNumProcs != numProcs { if actualNumProcs != numProcs {
logger.Warnf("Specified max procs of %v but using %v", numProcs, actualNumProcs) util.Log().Warnf("Specified max procs of %v but using %v", numProcs, actualNumProcs)
} }
} }

View File

@ -2,11 +2,12 @@ package route
import ( import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/flosch/pongo2"
"net/http" "net/http"
"amuz.es/go/mnemonics/util"
) )
func Index(c *gin.Context) { func Index(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", pongo2.Context{}) c.HTML(http.StatusOK, "index.html", util.Context{})
} }

View File

@ -6,10 +6,25 @@ package util
import ( import (
"time" "time"
"os"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
var logger = logrus.New()
func InitLogger() {
// logging framework
logger.Level = logrus.ErrorLevel
logger.Out = os.Stderr
}
func Log() *logrus.Logger {
// logging framework
return logger
}
// Ginrus returns a gin.HandlerFunc (middleware) that logs requests using logrus. // Ginrus returns a gin.HandlerFunc (middleware) that logs requests using logrus.
// //
// Requests with errors are logged using logrus.Error(). // Requests with errors are logged using logrus.Error().
@ -18,7 +33,7 @@ import (
// It receives: // It receives:
// 1. A time package format string (e.g. time.RFC3339). // 1. A time package format string (e.g. time.RFC3339).
// 2. A boolean stating whether to use UTC time zone or local. // 2. A boolean stating whether to use UTC time zone or local.
func Ginrus(logger *logrus.Logger, timeFormat string, utc bool) gin.HandlerFunc { func Ginrus(timeFormat string, utc bool) gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
start := time.Now() start := time.Now()
// some evil middlewares modify this values // some evil middlewares modify this values

View File

@ -2,70 +2,99 @@ package util
import ( import (
"net/http" "net/http"
"path"
"bytes"
"io"
"path/filepath"
"amuz.es/go/mnemonics/bind/template" "amuz.es/go/mnemonics/bind/template"
"github.com/flosch/pongo2" "github.com/flosch/pongo2"
"github.com/gin-gonic/gin/render" "github.com/gin-gonic/gin/render"
) )
// RenderOptions is used to configure the renderer. type (
type RenderOptions struct { PongoRelease struct {
ContentType string templateSet *pongo2.TemplateSet
} Path string
}
// Pongo2Render is a custom Gin template renderer using Pongo2. PongoDebug struct {
type Pongo2Render struct { Path string
Options *RenderOptions }
Pongo struct {
Template *pongo2.Template Template *pongo2.Template
Name string
Data interface{}
}
Context pongo2.Context Context pongo2.Context
)
func TemplateSourceRelease(path string) *PongoRelease {
ts := pongo2.NewSet(path, &memoryTemplateLoader{loaderFunc: template.Asset})
return &PongoRelease{ts, path}
} }
// New creates a new Pongo2Render instance with custom Options. func (p PongoRelease) Instance(name string, data interface{}) render.Render {
func New(options RenderOptions) *Pongo2Render { t := pongo2.Must(p.templateSet.FromFile(path.Join(p.Path, name)))
return &Pongo2Render{
Options: &options, return Pongo{
Template: t,
Name: name,
Data: data,
}
}
func TemplateSourceDebug(path string) *PongoDebug {
return &PongoDebug{path}
}
func (p PongoDebug) Instance(name string, data interface{}) render.Render {
t := pongo2.Must(pongo2.FromFile(path.Join(p.Path, name)))
return Pongo{
Template: t,
Name: name,
Data: data,
} }
} }
// Default creates a Pongo2Render instance with default options. func (p Pongo) Render(w http.ResponseWriter) error {
func Default() *Pongo2Render { ctx := pongo2.Context(p.Data.(Context))
return New(RenderOptions{ w.Header().Set("Content-Type", "text/html; charset=utf-8")
ContentType: "text/html; charset=utf-8", return p.Template.ExecuteWriter(ctx, w)
})
} }
// Instance should return a new Pongo2Render struct per request and prepare type memoryTemplateLoader struct {
// the template by either loading it from disk or using pongo2's cache. loaderFunc func(path string) ([]byte, error)
func (p Pongo2Render) Instance(name string, data interface{}) render.Render { fallbackLoader *pongo2.TemplateLoader
var templateResult *pongo2.Template }
// always read template files from disk if in debug mode, use cache otherwise.
//if gin.Mode() == "debug" {Render
// template = pongo2.Must(pongo2.FromFile(filename))
//} else {
// template = pongo2.Must(pongo2.FromCache(filename))
//}
templateContent:=template.MustAsset(name)
templateResult=pongo2.Must(pongo2.FromString(string(templateContent[:]))) func (m memoryTemplateLoader) Abs(base, name string) string {
if filepath.IsAbs(name) || base == "" {
return Pongo2Render{ return name
Template: templateResult,
Context: data.(pongo2.Context),
Options: p.Options,
} }
}
// Render should render the template to the response. if name == "" {
func (p Pongo2Render) Render(w http.ResponseWriter) error { return base
writeContentType(w, []string{p.Options.ContentType})
err := p.Template.ExecuteWriter(p.Context, w)
return err
}
// writeContentType is also in the gin/render package but it has not been made
// pubic so is repeated here, maybe convince the author to make this public.
func writeContentType(w http.ResponseWriter, value []string) {
header := w.Header()
if val := header["Content-Type"]; len(val) == 0 {
header["Content-Type"] = value
} }
return filepath.Dir(base) + string(filepath.Separator) + name
}
func (m memoryTemplateLoader) Get(path string) (io.Reader, error) {
Log().Errorf("hello template %s", filepath.Clean(path))
// t := pongo2.Must(p.templateSet.FromFile(path.Join(p.Path, name)))
data, err := m.loaderFunc(path)
if err != nil {
if m.fallbackLoader != nil {
return (*m.fallbackLoader).Get(path)
}
return nil, err
}
return bytes.NewReader(data), nil
} }