I have a init() function defined in "config/config.go"
config.go
package config
import(
log "github.com/sirupsen/logrus"
)
func init() {
log.SetReportCaller(true)
}
I have another go file called auth.go in auth package
package auth
import(
log "github.com/sirupsen/logrus"
)
func auth(username string, pwd string) {
//some auth code
log.Info("Auth success")
}
When log.Info() is called in auth.go the log prints as below
2018-11-09T16:38:27+05:30 auth/auth.go:36 level=info msg="Auth success"
What I am confused here is that, how "log" in auth.go is aware of the settings done in config.go
. log.SetReportCaller()
is in config.go
but even when auth.go
is logged it takes settings of log.SetReportCaller() done in config.go
Since log.SetReportCaller() is not set in auth.go expected log should be as below without showing line number of caller method.
2018-11-09T16:38:27+05:30 level=info msg="Auth success"
main.go
package main
import (
"path/to/auth"
log "github.com/sirupsen/logrus"
"net/http"
)
func main() {
r := server.Route()
log.Info("Listening on 8080")
http.Handle("/", r)
log.Fatal(http.ListenAndServe(":8080", nil))
}
auth/router.go
package auth
import (
"github.com/gorilla/mux"
"github.com/rs/cors"
"net/http"
)
func Route() http.Handler {
r := mux.NewRouter()
// UI handlers
r.HandleFunc("/", IndexPageHandler)
r.HandleFunc("/login", LoginHandler).Methods("POST")
handler := cors.Default().Handler(r)
return
}
auth/login.go
package auth
import (
"fmt"
"path/to/config"
log "github.com/sirupsen/logrus"
"net/http"
)
func LoginHandler(w http.ResponseWriter, r *http.Request) {
username := r.FormValue("username")
password := r.FormValue("password")
status, userName, mail, _ := auth(username, password)
//some code goes here
}
Kindly explain how this is happening
Check this diagram to understand how init()
work: diagram
Initialization order are as follows,
If a package imports other packages, the imported packages are initialised first.
Package level variables are initialised then.
init function of current package is called next. A package can have multiple init functions (either in a single file or distributed across multiple files) and they are called in the order in which they are presented to the compiler.
You will found an example explaining this here.
I am suspecting in dependency tree, there is a common ancestor file that import both config
package and auth
package.
Here is official doc on initialization: Package initialization
UPD: As you have added respective codes, let's visualize what is happening here. Look at the picture bellow,
What happening:
log.SetReportCaller(true)
is called).main()
function starts executing...The behavior you're asking about actually has nothing to do with how init()
functions work. SetReportCaller
sets a global variable in github.com/sirupsen/logrus
, not in your config
or auth
packages. So it doesn't matter where you call that function or where you call log.Info
et al; the setting affects all calls to logrus regardless of call origin.