mirror of
https://github.com/kataras/iris.git
synced 2025-12-18 10:27:06 +00:00
Update to 8.1.0 - a new logger implemented as a solution for https://github.com/kataras/iris/issues/680
Former-commit-id: 765b43602655fad7f525ca7a5f7f297a6167d075
This commit is contained in:
@@ -7,7 +7,7 @@ go:
|
||||
- tip
|
||||
go_import_path: github.com/kataras/iris
|
||||
install:
|
||||
- go get ./... # for iris-contrib/httpexpect and sirupsen/logrus
|
||||
- go get ./... # for iris-contrib/httpexpect and kataras/golog
|
||||
script:
|
||||
- go test -v -cover ./...
|
||||
after_script:
|
||||
|
||||
36
HISTORY.md
36
HISTORY.md
@@ -13,10 +13,46 @@
|
||||
### Should I upgrade my Iris?
|
||||
|
||||
Developers are not forced to upgrade if they don't really need it. Upgrade whenever you feel ready.
|
||||
|
||||
> Iris uses the [vendor directory](https://docs.google.com/document/d/1Bz5-UB7g2uPBdOx-rw5t9MxJwkfpx90cqG9AFL0JAYo) feature, so you get truly reproducible builds, as this method guards against upstream renames and deletes.
|
||||
|
||||
**How to upgrade**: Open your command-line and execute this command: `go get -u github.com/kataras/iris`.
|
||||
|
||||
|
||||
# We, 26 July 2017 | v8.1.0
|
||||
|
||||
The `app.Logger() *logrus.Logger` was replaced with a custom implementation [[golog](https://github.com/kataras/golog)], it's compatible with the [logrus](https://github.com/sirupsen/logrus) package and other open-source golang loggers as well, because of that: https://github.com/kataras/iris/issues/680#issuecomment-316184570.
|
||||
|
||||
The API didn't change much except these:
|
||||
|
||||
- the new implementation does not recognise `Fatal` and `Panic` because, actually, iris never panics
|
||||
- the old `app.Logger().Out = io.Writer` should be written as `app.Logger().SetOutput(io.Writer)`
|
||||
|
||||
The new implementation, [golog](https://github.com/kataras/golog) is more featured
|
||||
and it completes more use cases than the before external implementation.
|
||||
|
||||
At general you have to know that the low-level relative fields and functions are actually inside `app.Logger().Printer` object, i.e: `app.Logger().Printer.Output` to get the `io.Writer` or `app.Logger().Printer.AddOuput/SetOutput` to set or add more output(`io.Writer`) targets.
|
||||
|
||||
### Integration
|
||||
|
||||
I understand that many of you may use logrus outside of Iris too. To integrate an external `logrus` logger just
|
||||
`Install` it-- all print operations will be handled by the provided `logrus instance`.
|
||||
|
||||
```go
|
||||
import (
|
||||
"github.com/kataras/iris"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
package main(){
|
||||
app := iris.New()
|
||||
app.Logger().Install(logrus.StandardLogger()) // the package-level logrus instance
|
||||
// [...]
|
||||
}
|
||||
```
|
||||
|
||||
For more information about our new logger please navigate to: https://github.com/kataras/golog - contributions are welcomed as well!
|
||||
|
||||
# Sa, 23 July 2017 | v8.0.7
|
||||
|
||||
Fix [It's true that with UseGlobal the "/path1.txt" route call the middleware but cause the prepend, the order is inversed](https://github.com/kataras/iris/issues/683#issuecomment-317229068)
|
||||
|
||||
@@ -17,7 +17,7 @@ Iris is a fast, simple and efficient micro web framework for Go. It provides a b
|
||||
### 📑 Table of contents
|
||||
|
||||
* [Installation](#-installation)
|
||||
* [Latest changes](https://github.com/kataras/iris/blob/master/HISTORY.md#sa-23-july-2017--v807)
|
||||
* [Latest changes](https://github.com/kataras/iris/blob/master/HISTORY.md#we-26-july-2017--v810)
|
||||
* [Learn](#-learn)
|
||||
* [HTTP Listening](_examples/#http-listening)
|
||||
* [Configuration](_examples/#configuration)
|
||||
@@ -339,7 +339,7 @@ Thank You for your trust!
|
||||
|
||||
### 📌 Version
|
||||
|
||||
Current: **8.0.7**
|
||||
Current: **8.1.0**
|
||||
|
||||
Each new release is pushed to the master. It stays there until the next version. When a next version is released then the previous version goes to its own branch with `gopkg.in` as its import path (and its own vendor folder), in order to keep it working "for-ever".
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
stdContext "context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -14,7 +13,7 @@ import (
|
||||
func logger(app *iris.Application) *bytes.Buffer {
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
app.Logger().Out = buf
|
||||
app.Logger().SetOutput(buf)
|
||||
|
||||
// disable the "Now running at...." in order to have a clean log of the error.
|
||||
// we could attach that on `Run` but better to keep things simple here.
|
||||
@@ -41,20 +40,12 @@ func TestListenAddr(t *testing.T) {
|
||||
t.Fatalf("expecting err to be `iris.ErrServerClosed` but got: %v", err)
|
||||
}
|
||||
|
||||
// println(log.Bytes())
|
||||
// println(len(log.Bytes()))
|
||||
expectedMessage := iris.ErrServerClosed.Error()
|
||||
|
||||
expected := fmt.Sprintln("\"" + iris.ErrServerClosed.Error() + "\" ")
|
||||
expected = strings.TrimSpace(expected)
|
||||
// println([]byte(expected))
|
||||
// println(len([]byte(expected)))
|
||||
|
||||
got := log.String()
|
||||
got = strings.Split(got, "msg=")[1]
|
||||
got = strings.TrimSpace(got)
|
||||
if expected != got {
|
||||
t.Fatalf("expecting to log the:\n'%s'\ninstead of:\n'%s'", expected, got)
|
||||
if got := log.String(); !strings.Contains(got, expectedMessage) {
|
||||
t.Fatalf("expecting to log to contains the:\n'%s'\ninstead of:\n'%s'", expectedMessage, got)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestListenAddrWithoutServerErr(t *testing.T) {
|
||||
|
||||
@@ -18,7 +18,8 @@ func main() {
|
||||
Method: true,
|
||||
// Path displays the request path
|
||||
Path: true,
|
||||
// Columns: true,
|
||||
|
||||
//Columns: true,
|
||||
|
||||
// if !empty then its contents derives from `ctx.Values().Get("logger_message")
|
||||
// will be added to the logs.
|
||||
@@ -57,6 +58,6 @@ func main() {
|
||||
// http://localhost:8080/2
|
||||
// http://lcoalhost:8080/notfoundhere
|
||||
// see the output on the console.
|
||||
app.Run(iris.Addr(":8080"))
|
||||
app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed))
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func main() {
|
||||
// http://localhost:8080/1
|
||||
// http://localhost:8080/2
|
||||
// http://lcoalhost:8080/notfoundhere
|
||||
app.Run(iris.Addr(":8080"))
|
||||
app.Run(iris.Addr(":8080"), iris.WithoutServerError(iris.ErrServerClosed))
|
||||
}
|
||||
|
||||
// get a filename based on the date, file logs works that way the most times
|
||||
|
||||
@@ -32,11 +32,11 @@ func main() {
|
||||
|
||||
app := iris.New()
|
||||
// attach the file as logger, remember, iris' app logger is just an io.Writer.
|
||||
app.Logger().Out = newLogFile()
|
||||
app.Logger().SetOutput(newLogFile())
|
||||
|
||||
app.Get("/", func(ctx context.Context) {
|
||||
// for the sake of simplicity, in order see the logs at the ./_today_.txt
|
||||
ctx.Application().Logger().Infoln("Request path: " + ctx.Path())
|
||||
ctx.Application().Logger().Info("Request path: " + ctx.Path())
|
||||
ctx.Writef("hello")
|
||||
})
|
||||
|
||||
@@ -44,7 +44,7 @@ func main() {
|
||||
// and open the ./logs.txt file
|
||||
if err := app.Run(iris.Addr(":8080"), iris.WithoutBanner); err != nil {
|
||||
if err != iris.ErrServerClosed {
|
||||
app.Logger().Warnln("Shutdown with error: " + err.Error())
|
||||
app.Logger().Warn("Shutdown with error: " + err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ func main() {
|
||||
// using the go v1.8's HTTP/2 Push.
|
||||
// Note that you have to listen using ListenTLS in order this to work.
|
||||
if err := ctx.ResponseWriter().Push("/js/chat.js", nil); err != nil {
|
||||
ctx.Application().Logger().Warnln(err.Error())
|
||||
ctx.Application().Logger().Warn(err.Error())
|
||||
}
|
||||
ctx.ViewData("", clientPage{"Client Page", ctx.Host()})
|
||||
ctx.View("client.html")
|
||||
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/kataras/golog"
|
||||
)
|
||||
|
||||
// Application is the context's owner.
|
||||
@@ -14,8 +14,8 @@ type Application interface {
|
||||
// ConfigurationReadOnly returns all the available configuration values can be used on a request.
|
||||
ConfigurationReadOnly() ConfigurationReadOnly
|
||||
|
||||
// Logger returns the logrus logger instance(pointer) that is being used inside the "app".
|
||||
Logger() *logrus.Logger
|
||||
// Logger returns the golog logger instance(pointer) that is being used inside the "app".
|
||||
Logger() *golog.Logger
|
||||
|
||||
// View executes and write the result of a template file to the writer.
|
||||
//
|
||||
|
||||
@@ -2231,7 +2231,7 @@ func (ctx *context) BeginTransaction(pipe func(t *Transaction)) {
|
||||
t := newTransaction(ctx) // it calls this *context, so the overriding with a new pool's New of context.Context wil not work here.
|
||||
defer func() {
|
||||
if err := recover(); err != nil {
|
||||
ctx.Application().Logger().Warnln(errTransactionInterrupted.Format(err).Error())
|
||||
ctx.Application().Logger().Warn(errTransactionInterrupted.Format(err).Error())
|
||||
// complete (again or not , doesn't matters) the scope without loud
|
||||
t.Complete(nil)
|
||||
// we continue as normal, no need to return here*
|
||||
|
||||
2
doc.go
2
doc.go
@@ -35,7 +35,7 @@ Source code and other details for the project are available at GitHub:
|
||||
|
||||
Current Version
|
||||
|
||||
8.0.7
|
||||
8.1.0
|
||||
|
||||
Installation
|
||||
|
||||
|
||||
33
iris.go
33
iris.go
@@ -10,7 +10,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/kataras/golog"
|
||||
|
||||
// context for the handlers
|
||||
"github.com/kataras/iris/context"
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
const (
|
||||
|
||||
// Version is the current version number of the Iris Web Framework.
|
||||
Version = "8.0.7"
|
||||
Version = "8.1.0"
|
||||
)
|
||||
|
||||
// HTTP status codes as registered with IANA.
|
||||
@@ -137,8 +137,8 @@ type Application struct {
|
||||
// all fields defaults to something that is working, developers don't have to set it.
|
||||
config *Configuration
|
||||
|
||||
// the logrus logger instance, defaults to "Info" level messages (all except "Debug")
|
||||
logger *logrus.Logger
|
||||
// the golog logger instance, defaults to "Info" level messages (all except "Debug")
|
||||
logger *golog.Logger
|
||||
|
||||
// view engine
|
||||
view view.View
|
||||
@@ -163,7 +163,7 @@ func New() *Application {
|
||||
|
||||
app := &Application{
|
||||
config: &config,
|
||||
logger: logrus.New(),
|
||||
logger: golog.Default,
|
||||
APIBuilder: router.NewAPIBuilder(),
|
||||
Router: router.NewRouter(),
|
||||
}
|
||||
@@ -207,20 +207,19 @@ func (app *Application) ConfigurationReadOnly() context.ConfigurationReadOnly {
|
||||
// These are the different logging levels. You can set the logging level to log
|
||||
// on the application 's instance of logger, obtained with `app.Logger()`.
|
||||
//
|
||||
// These are conversions from logrus.
|
||||
// These are conversions from golog.
|
||||
const (
|
||||
// NoLog level, logs nothing.
|
||||
// It's the logrus' `PanicLevel` but it never used inside iris so it will never log.
|
||||
NoLog = logrus.PanicLevel
|
||||
NoLog = golog.DisableLevel
|
||||
// ErrorLevel level. Logs. Used for errors that should definitely be noted.
|
||||
// Commonly used for hooks to send errors to an error tracking service.
|
||||
ErrorLevel = logrus.ErrorLevel
|
||||
ErrorLevel = golog.ErrorLevel
|
||||
// WarnLevel level. Non-critical entries that deserve eyes.
|
||||
WarnLevel = logrus.WarnLevel
|
||||
WarnLevel = golog.WarnLevel
|
||||
)
|
||||
|
||||
// Logger returns the logrus logger instance(pointer) that is being used inside the "app".
|
||||
func (app *Application) Logger() *logrus.Logger {
|
||||
// Logger returns the golog logger instance(pointer) that is being used inside the "app".
|
||||
func (app *Application) Logger() *golog.Logger {
|
||||
return app.logger
|
||||
}
|
||||
|
||||
@@ -264,13 +263,13 @@ func (app *Application) RegisterView(viewEngine view.Engine) {
|
||||
func (app *Application) View(writer io.Writer, filename string, layout string, bindingData interface{}) error {
|
||||
if app.view.Len() == 0 {
|
||||
err := errors.New("view engine is missing, use `RegisterView`")
|
||||
app.Logger().Errorln(err)
|
||||
app.Logger().Error(err)
|
||||
return err
|
||||
}
|
||||
|
||||
err := app.view.ExecuteWriter(writer, filename, layout, bindingData)
|
||||
if err != nil {
|
||||
app.Logger().Errorln(err)
|
||||
app.Logger().Error(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
@@ -328,7 +327,7 @@ func (app *Application) NewHost(srv *http.Server) *host.Supervisor {
|
||||
|
||||
// check if different ErrorLog provided, if not bind it with the framework's logger
|
||||
if srv.ErrorLog == nil {
|
||||
srv.ErrorLog = log.New(app.logger.Out, "[HTTP Server] ", 0)
|
||||
srv.ErrorLog = log.New(app.logger.Printer.Output, "[HTTP Server] ", 0)
|
||||
}
|
||||
|
||||
if srv.Addr == "" {
|
||||
@@ -352,7 +351,7 @@ func (app *Application) NewHost(srv *http.Server) *host.Supervisor {
|
||||
|
||||
if !app.config.DisableStartupLog {
|
||||
// show the available info to exit from app.
|
||||
su.RegisterOnServe(host.WriteStartupLogOnServe(app.logger.Out)) // app.logger.Writer -> Info
|
||||
su.RegisterOnServe(host.WriteStartupLogOnServe(app.logger.Printer.Output)) // app.logger.Writer -> Info
|
||||
}
|
||||
|
||||
if !app.config.DisableInterruptHandler {
|
||||
@@ -543,7 +542,7 @@ func (app *Application) Run(serve Runner, withOrWithout ...Configurator) error {
|
||||
// this will block until an error(unless supervisor's DeferFlow called from a Task).
|
||||
err := serve(app)
|
||||
if err != nil {
|
||||
app.Logger().Errorln(err)
|
||||
app.Logger().Error(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -79,14 +79,15 @@ func (l *requestLoggerMiddleware) ServeHTTP(ctx context.Context) {
|
||||
logFunc(endTime, latency, status, ip, method, path, message)
|
||||
return
|
||||
}
|
||||
endTimeFormatted := endTime.Format("2006/01/02 - 15:04:05")
|
||||
|
||||
if l.config.Columns {
|
||||
endTimeFormatted := endTime.Format("2006/01/02 - 15:04:05")
|
||||
output := Columnize(endTimeFormatted, latency, status, ip, method, path, message)
|
||||
ctx.Application().Logger().Out.Write([]byte(output))
|
||||
ctx.Application().Logger().Printer.Output.Write([]byte(output))
|
||||
return
|
||||
}
|
||||
// no new line, the framework's logger is responsible how to render each log.
|
||||
line := fmt.Sprintf("%s | %v %4v %s %s %s", endTimeFormatted, status, latency, ip, method, path)
|
||||
line := fmt.Sprintf("%v %4v %s %s %s", status, latency, ip, method, path)
|
||||
if message != nil {
|
||||
line += fmt.Sprintf(" %v", message)
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ func New() context.Handler {
|
||||
logMessage += fmt.Sprintf("At Request: %s\n", getRequestLogs(ctx))
|
||||
logMessage += fmt.Sprintf("Trace: %s\n", err)
|
||||
logMessage += fmt.Sprintf("\n%s", stacktrace)
|
||||
ctx.Application().Logger().Warnln(logMessage)
|
||||
ctx.Application().Logger().Warn(logMessage)
|
||||
|
||||
ctx.StatusCode(500)
|
||||
ctx.StopExecution()
|
||||
|
||||
Reference in New Issue
Block a user