Question about Iris Logging: How to access a logger in other parts of application
Env Details:
Iris Version: 12.2.0
go version go1.19.4 darwin/arm64
I am trying to setup my new Iris application as follows:
// main.go
package main
import (
"myapp/bootstrap"
"github.com/kataras/iris/v12"
)
func main() {
bootstrap.InitIrisApp()
app := bootstrap.GetIrisApp()
app.Listen(util.GetPortNumber(), iris.WithLowercaseRouting)
}
The bootstrap.go looks like below:
package bootstrap
import (
"myapp/handler"
"myapp/structs"
"myapp/util"
"strings"
"time"
prometheusMiddleware "github.com/iris-contrib/middleware/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/kataras/golog"
"github.com/kataras/iris/v12"
)
var irisServer *iris.Application
func getRequestLogger(ctx iris.Context) {
// write log format as below format
// $remote_addr $http_method $http_uri $http_user_agent
ctx.Request().UserAgent()
ctx.Request().Referer()
template := "Remote Addr: %s | Path: %s %s | UA: %s "
ctx.Application().Logger().Infof(template, ctx.RemoteAddr(), ctx.Method(), ctx.Path(), ctx.Request().UserAgent())
ctx.Next()
}
func InitIrisApp() {
// initialize default app with default middlewares
irisServer = iris.Default()
// configure logger
initLogger()
// configure health check
initHealthCheck()
// configure prometheus metrics and end points
initPrometheusMetrics()
// initRoutes
initRoutes()
// configure the env configuration
// configure error handlers
irisServer.OnErrorCode(iris.StatusInternalServerError, internalServerErrorHandler)
// configure graceful shutdown
}
func initHealthCheck() {
hcAPI := irisServer.Party(util.GetContextPath() + "/health")
{
hcAPI.Get("/status", func(ctx iris.Context) {
ctx.JSON(handler.HealthHandlerIris())
})
}
}
func initRoutes() {
jobsAPI := irisServer.Party(util.GetContextPath() + "/jobs")
{
// bind more routes
}
}
func internalServerErrorHandler(ctx iris.Context) {
msg := strings.Split(ctx.GetErr().Error(), "\n")
ctx.JSON(structs.ServerErrorResponse{
StatusCode: 500,
Message: "Unable to process the request. Internal Server error!",
Description: msg[0],
Path: ctx.Path(),
Timestamp: time.Now(),
ApiVersion: util.GetAPIVersion(),
})
}
func initPrometheusMetrics() {
// adding middleware for prometheus
m := prometheusMiddleware.New("serviceName", 0.3, 1.2, 5.0)
irisServer.Use(m.ServeHTTP)
// adding a route for getting prometheus metrics
irisServer.Get("/prometrics", iris.FromStd(promhttp.Handler()))
}
func initLogger() {
irisServer.Logger().SetLevel(util.GetRunLogLevel())
// adding a middleware for logging requests
irisServer.Use(getRequestLogger)
}
func GetLoggerInstance() *golog.Logger {
return irisServer.Logger()
}
func GetIrisApp() *iris.Application {
return irisServer
}
I want to understand once I have setup the logger I want to use it in other parts of the code, like Handlers, service layers, models etc. For this reason I exported a function GetLoggerInstance() in hope that I can use same logger instance in whole code. But I land up in cyclic dependency. Moreover, when I am to use logging methods the correct context of the log must be picked up.
[19:01:49 IST 2023/07/26] [DEFAULT] [INFO] (myapp/util/config:8) Setting project directory as.....
[INFO] 2023/07/26 19:13 Remote Addr: ::1 | Path: GET /api/health/status | UA: PostmanRuntime/7.32.0
I understand the access logs and different from application logs, but how can I achieve the parity between both of them using iris logger. Unfortunately I was not able to understand this from Docs. Any help is much appreciated. @kataras
Hello @ce-ankur did you try?
func myHandler(ctx iris.Context) {
logger := ctx.Application().Logger()
// work with "logger" instance...
}
HI @kataras
This is the easiest approach and I am already using this in my handlers/where-ever the ctx object is available.
I question was regarding how can I get logger instance where I don't have context object. I don't think passing either logger or ctx instance is a good idea.
@ce-ankur If you use the default Iris logger you can get the logger instance through golog.Default/golog.Debug/Info... so you don't have dependency cycle.