How golang's init() works. I am confused









up vote
-5
down vote

favorite












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










share|improve this question























  • can you show the file where your main function is. I am suspecting that file imports config package.
    – Emruz Hossain
    2 days ago











  • question is updated with main.go code
    – Aditya C S
    2 days ago






  • 2




    We can't see the dependency tree so I'm guessing config is a dependency somewhere here. if that is the case, it is not mystery why the init() function is called.
    – ssemilla
    2 days ago














up vote
-5
down vote

favorite












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










share|improve this question























  • can you show the file where your main function is. I am suspecting that file imports config package.
    – Emruz Hossain
    2 days ago











  • question is updated with main.go code
    – Aditya C S
    2 days ago






  • 2




    We can't see the dependency tree so I'm guessing config is a dependency somewhere here. if that is the case, it is not mystery why the init() function is called.
    – ssemilla
    2 days ago












up vote
-5
down vote

favorite









up vote
-5
down vote

favorite











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










share|improve this question















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







go






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited yesterday

























asked 2 days ago









Aditya C S

130128




130128











  • can you show the file where your main function is. I am suspecting that file imports config package.
    – Emruz Hossain
    2 days ago











  • question is updated with main.go code
    – Aditya C S
    2 days ago






  • 2




    We can't see the dependency tree so I'm guessing config is a dependency somewhere here. if that is the case, it is not mystery why the init() function is called.
    – ssemilla
    2 days ago
















  • can you show the file where your main function is. I am suspecting that file imports config package.
    – Emruz Hossain
    2 days ago











  • question is updated with main.go code
    – Aditya C S
    2 days ago






  • 2




    We can't see the dependency tree so I'm guessing config is a dependency somewhere here. if that is the case, it is not mystery why the init() function is called.
    – ssemilla
    2 days ago















can you show the file where your main function is. I am suspecting that file imports config package.
– Emruz Hossain
2 days ago





can you show the file where your main function is. I am suspecting that file imports config package.
– Emruz Hossain
2 days ago













question is updated with main.go code
– Aditya C S
2 days ago




question is updated with main.go code
– Aditya C S
2 days ago




2




2




We can't see the dependency tree so I'm guessing config is a dependency somewhere here. if that is the case, it is not mystery why the init() function is called.
– ssemilla
2 days ago




We can't see the dependency tree so I'm guessing config is a dependency somewhere here. if that is the case, it is not mystery why the init() function is called.
– ssemilla
2 days ago












2 Answers
2






active

oldest

votes

















up vote
3
down vote



accepted










Check this diagram to understand how init() work: diagram



Initialization order are as follows,



  1. If a package imports other packages, the imported packages are initialised first.


  2. Package level variables are initialised then.


  3. 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,



enter image description here



What happening:



  1. Your main package start initialing. But it is has imported auth package. So to complete initialization, auth package must be initialized.


  2. auth package start initializing. But it has imported config package. So to complete initialization, config package must be initialized.


  3. config package complete initialization(log.SetReportCaller(true) is called).


  4. auth package complete initialization.


  5. main package complete initialization.


  6. main() function starts executing...





share|improve this answer






















  • @peterSO thank you for pointing me there. I have updated my answer to include this information.
    – Emruz Hossain
    2 days ago










  • I have added all the dependent code. Kindly refer the edited question and throw me some light on how dependency is working here.
    – Aditya C S
    yesterday










  • @AdityaCS I have updated my answer to explain what is happening.
    – Emruz Hossain
    yesterday










  • thanks for the explanation. Still my doubt is, is the "log" package imported and referenced in main.go the same as "log" imported and referenced in config.go. Both imports has different "log" reference right? How it still works?
    – Aditya C S
    yesterday







  • 1




    @Adrian has already answer this in his answer. "SetReportCaller sets a global variable in github.com/sirupsen/logrus" . All imports from different packages refers to same instance until you create new one using logrus.New()
    – Emruz Hossain
    yesterday

















up vote
1
down vote













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.






share|improve this answer




















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53224684%2fhow-golangs-init-works-i-am-confused%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    3
    down vote



    accepted










    Check this diagram to understand how init() work: diagram



    Initialization order are as follows,



    1. If a package imports other packages, the imported packages are initialised first.


    2. Package level variables are initialised then.


    3. 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,



    enter image description here



    What happening:



    1. Your main package start initialing. But it is has imported auth package. So to complete initialization, auth package must be initialized.


    2. auth package start initializing. But it has imported config package. So to complete initialization, config package must be initialized.


    3. config package complete initialization(log.SetReportCaller(true) is called).


    4. auth package complete initialization.


    5. main package complete initialization.


    6. main() function starts executing...





    share|improve this answer






















    • @peterSO thank you for pointing me there. I have updated my answer to include this information.
      – Emruz Hossain
      2 days ago










    • I have added all the dependent code. Kindly refer the edited question and throw me some light on how dependency is working here.
      – Aditya C S
      yesterday










    • @AdityaCS I have updated my answer to explain what is happening.
      – Emruz Hossain
      yesterday










    • thanks for the explanation. Still my doubt is, is the "log" package imported and referenced in main.go the same as "log" imported and referenced in config.go. Both imports has different "log" reference right? How it still works?
      – Aditya C S
      yesterday







    • 1




      @Adrian has already answer this in his answer. "SetReportCaller sets a global variable in github.com/sirupsen/logrus" . All imports from different packages refers to same instance until you create new one using logrus.New()
      – Emruz Hossain
      yesterday














    up vote
    3
    down vote



    accepted










    Check this diagram to understand how init() work: diagram



    Initialization order are as follows,



    1. If a package imports other packages, the imported packages are initialised first.


    2. Package level variables are initialised then.


    3. 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,



    enter image description here



    What happening:



    1. Your main package start initialing. But it is has imported auth package. So to complete initialization, auth package must be initialized.


    2. auth package start initializing. But it has imported config package. So to complete initialization, config package must be initialized.


    3. config package complete initialization(log.SetReportCaller(true) is called).


    4. auth package complete initialization.


    5. main package complete initialization.


    6. main() function starts executing...





    share|improve this answer






















    • @peterSO thank you for pointing me there. I have updated my answer to include this information.
      – Emruz Hossain
      2 days ago










    • I have added all the dependent code. Kindly refer the edited question and throw me some light on how dependency is working here.
      – Aditya C S
      yesterday










    • @AdityaCS I have updated my answer to explain what is happening.
      – Emruz Hossain
      yesterday










    • thanks for the explanation. Still my doubt is, is the "log" package imported and referenced in main.go the same as "log" imported and referenced in config.go. Both imports has different "log" reference right? How it still works?
      – Aditya C S
      yesterday







    • 1




      @Adrian has already answer this in his answer. "SetReportCaller sets a global variable in github.com/sirupsen/logrus" . All imports from different packages refers to same instance until you create new one using logrus.New()
      – Emruz Hossain
      yesterday












    up vote
    3
    down vote



    accepted







    up vote
    3
    down vote



    accepted






    Check this diagram to understand how init() work: diagram



    Initialization order are as follows,



    1. If a package imports other packages, the imported packages are initialised first.


    2. Package level variables are initialised then.


    3. 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,



    enter image description here



    What happening:



    1. Your main package start initialing. But it is has imported auth package. So to complete initialization, auth package must be initialized.


    2. auth package start initializing. But it has imported config package. So to complete initialization, config package must be initialized.


    3. config package complete initialization(log.SetReportCaller(true) is called).


    4. auth package complete initialization.


    5. main package complete initialization.


    6. main() function starts executing...





    share|improve this answer














    Check this diagram to understand how init() work: diagram



    Initialization order are as follows,



    1. If a package imports other packages, the imported packages are initialised first.


    2. Package level variables are initialised then.


    3. 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,



    enter image description here



    What happening:



    1. Your main package start initialing. But it is has imported auth package. So to complete initialization, auth package must be initialized.


    2. auth package start initializing. But it has imported config package. So to complete initialization, config package must be initialized.


    3. config package complete initialization(log.SetReportCaller(true) is called).


    4. auth package complete initialization.


    5. main package complete initialization.


    6. main() function starts executing...






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited yesterday

























    answered 2 days ago









    Emruz Hossain

    55316




    55316











    • @peterSO thank you for pointing me there. I have updated my answer to include this information.
      – Emruz Hossain
      2 days ago










    • I have added all the dependent code. Kindly refer the edited question and throw me some light on how dependency is working here.
      – Aditya C S
      yesterday










    • @AdityaCS I have updated my answer to explain what is happening.
      – Emruz Hossain
      yesterday










    • thanks for the explanation. Still my doubt is, is the "log" package imported and referenced in main.go the same as "log" imported and referenced in config.go. Both imports has different "log" reference right? How it still works?
      – Aditya C S
      yesterday







    • 1




      @Adrian has already answer this in his answer. "SetReportCaller sets a global variable in github.com/sirupsen/logrus" . All imports from different packages refers to same instance until you create new one using logrus.New()
      – Emruz Hossain
      yesterday
















    • @peterSO thank you for pointing me there. I have updated my answer to include this information.
      – Emruz Hossain
      2 days ago










    • I have added all the dependent code. Kindly refer the edited question and throw me some light on how dependency is working here.
      – Aditya C S
      yesterday










    • @AdityaCS I have updated my answer to explain what is happening.
      – Emruz Hossain
      yesterday










    • thanks for the explanation. Still my doubt is, is the "log" package imported and referenced in main.go the same as "log" imported and referenced in config.go. Both imports has different "log" reference right? How it still works?
      – Aditya C S
      yesterday







    • 1




      @Adrian has already answer this in his answer. "SetReportCaller sets a global variable in github.com/sirupsen/logrus" . All imports from different packages refers to same instance until you create new one using logrus.New()
      – Emruz Hossain
      yesterday















    @peterSO thank you for pointing me there. I have updated my answer to include this information.
    – Emruz Hossain
    2 days ago




    @peterSO thank you for pointing me there. I have updated my answer to include this information.
    – Emruz Hossain
    2 days ago












    I have added all the dependent code. Kindly refer the edited question and throw me some light on how dependency is working here.
    – Aditya C S
    yesterday




    I have added all the dependent code. Kindly refer the edited question and throw me some light on how dependency is working here.
    – Aditya C S
    yesterday












    @AdityaCS I have updated my answer to explain what is happening.
    – Emruz Hossain
    yesterday




    @AdityaCS I have updated my answer to explain what is happening.
    – Emruz Hossain
    yesterday












    thanks for the explanation. Still my doubt is, is the "log" package imported and referenced in main.go the same as "log" imported and referenced in config.go. Both imports has different "log" reference right? How it still works?
    – Aditya C S
    yesterday





    thanks for the explanation. Still my doubt is, is the "log" package imported and referenced in main.go the same as "log" imported and referenced in config.go. Both imports has different "log" reference right? How it still works?
    – Aditya C S
    yesterday





    1




    1




    @Adrian has already answer this in his answer. "SetReportCaller sets a global variable in github.com/sirupsen/logrus" . All imports from different packages refers to same instance until you create new one using logrus.New()
    – Emruz Hossain
    yesterday




    @Adrian has already answer this in his answer. "SetReportCaller sets a global variable in github.com/sirupsen/logrus" . All imports from different packages refers to same instance until you create new one using logrus.New()
    – Emruz Hossain
    yesterday












    up vote
    1
    down vote













    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.






    share|improve this answer
























      up vote
      1
      down vote













      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.






      share|improve this answer






















        up vote
        1
        down vote










        up vote
        1
        down vote









        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.






        share|improve this answer












        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.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 2 days ago









        Adrian

        16.9k33446




        16.9k33446



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53224684%2fhow-golangs-init-works-i-am-confused%23new-answer', 'question_page');

            );

            Post as a guest














































































            Popular posts from this blog

            How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

            Syphilis

            Darth Vader #20