Meer informatie over het aanmelden bij Go

Voltooid

Logboeken spelen een belangrijke rol in een programma omdat ze een bron van informatie worden die u kunt controleren wanneer er iets misgaat. Wanneer er een fout optreedt, zien eindgebruikers meestal alleen een bericht dat een probleem met het programma aangeeft. Vanuit het perspectief van een ontwikkelaar hebben we meer informatie nodig dan een eenvoudig foutbericht. Dat komt vooral omdat we het probleem willen reproduceren om een juiste oplossing te schrijven. In deze module leert u hoe logboekregistratie werkt in Go. U leert ook enkele procedures die u altijd moet implementeren.

het pakket log

Om te beginnen biedt Go een eenvoudig standaardpakket voor het werken met logboeken. U kunt het gebruiken op een manier die lijkt op hoe u het fmt pakket gebruikt. Het standaardpakket biedt geen logboekniveaus en u kunt geen afzonderlijke logboekregistraties configureren voor elk pakket. Als u complexere logboekconfiguraties moet schrijven, kunt u dit doen met behulp van een framework voor logboekregistratie. Later behandelen we frameworks voor logboekregistratie.

Dit is de eenvoudigste manier om logboeken te gebruiken:

import (
    "log"
)

func main() {
    log.Print("Hey, I'm a log!")
}

Wanneer u de voorgaande code uitvoert, krijgt u deze uitvoer:

2020/12/19 13:39:17 Hey, I'm a log!

De functie bevat standaard log.Print() de datum en tijd als het voorvoegsel van het logboekbericht. U kunt hetzelfde gedrag krijgen met behulp van fmt.Print(), maar u kunt andere dingen doen met het log pakket, zoals het verzenden van logboeken naar een bestand. Later bekijken we meer log pakketfunctionaliteit.

U kunt de log.Fatal() functie gebruiken om een fout in te logboeken en het programma te beëindigen alsof u deze hebt gebruikt os.Exit(1). Als u het eens wilt proberen, gebruiken we dit codefragment:

package main

import (
    "fmt"
    "log"
)

func main() {
    log.Fatal("Hey, I'm an error log!")
    fmt.Print("Can you see me?")
}

Wanneer u de voorgaande code uitvoert, krijgt u deze uitvoer:

2020/12/19 13:53:19  Hey, I'm an error log!
exit status 1

U ziet dat de laatste regel, fmt.Print("Can you see me?")niet wordt uitgevoerd. Dat komt doordat de log.Fatal() functie-aanroep het programma stopt. U krijgt vergelijkbaar gedrag wanneer u de log.Panic() functie gebruikt, die ook de panic() functie aanroept, zoals deze:

package main

import (
    "fmt"
    "log"
)

func main() {
    log.Panic("Hey, I'm an error log!")
    fmt.Print("Can you see me?")
}

Wanneer u de voorgaande code uitvoert, krijgt u deze uitvoer:

2020/12/19 13:53:19  Hey, I'm an error log!
panic: Hey, I'm an error log!

goroutine 1 [running]:
log.Panic(0xc000060f58, 0x1, 0x1)
        /usr/local/Cellar/go/1.15.5/libexec/src/log/log.go:351 +0xae
main.main()
        /Users/christian/go/src/helloworld/logs.go:9 +0x65
exit status 2

U krijgt nog steeds het logboekbericht, maar nu krijgt u ook de foutstacktracering.

Een andere essentiële functie is log.SetPrefix(). U kunt het gebruiken om een voorvoegsel toe te voegen aan de logboekberichten van uw programma. U kunt bijvoorbeeld dit codefragment gebruiken:

package main

import (
    "log"
)

func main() {
    log.SetPrefix("main(): ")
    log.Print("Hey, I'm a log!")
    log.Fatal("Hey, I'm an error log!")
}

Wanneer u de voorgaande code uitvoert, krijgt u deze uitvoer:

main(): 2021/01/05 13:59:58 Hey, I'm a log!
main(): 2021/01/05 13:59:58 Hey, I'm an error log!
exit status 1

U stelt het voorvoegsel eenmaal in en uw logboeken bevatten informatie zoals de naam van de functie waaruit het logboek is gekomen.

U kunt andere functies op de Go-website verkennen.

Logboekregistratie naar een bestand

Naast het afdrukken van logboeken naar de console, wilt u mogelijk logboeken naar een bestand verzenden, zodat u ze later of in realtime kunt verwerken.

Waarom wilt u logboeken naar een bestand verzenden? Ten eerste wilt u mogelijk specifieke informatie verbergen voor uw eindgebruikers. Ze zijn mogelijk niet geïnteresseerd of u kunt gevoelige informatie blootstellen. Wanneer u logboeken in bestanden hebt, kunt u alle logboeken vervolgens centraliseren naar één locatie en deze correleren met andere gebeurtenissen. Dit patroon is typisch: gedistribueerde toepassingen die kortstondig kunnen zijn, zoals containers.

Laten we de volgende code gebruiken om het verzenden van logboeken naar een bestand te testen:

package main

import (
    "log"
    "os"
)

func main() {
    file, err := os.OpenFile("info.log", os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
    if err != nil {
        log.Fatal(err)
    }

    defer file.Close()

    log.SetOutput(file)
    log.Print("Hey, I'm a log!")
}

Wanneer u de voorgaande code uitvoert, ziet u niets in de console. In uw map ziet u een nieuw bestand met de naam info.log dat de logboeken bevat die u hebt verzonden met behulp van de log.Print() functie. U moet beginnen met het maken of openen van een bestand en vervolgens het log pakket configureren om alle uitvoer naar een bestand te verzenden. Vervolgens kunt u de log.Print() functie blijven gebruiken zoals u dat gewoonlijk zou doen.

Frameworks voor logboekregistratie

Ten slotte kan het zijn dat de functies van het log pakket niet voldoende zijn. Het kan handig zijn om een framework voor logboekregistratie te gebruiken in plaats van uw eigen bibliotheken te schrijven. Enkele frameworks voor logboekregistratie voor Go zijn Logrus, zerolog, zap en Apex.

Laten we eens kijken wat we met zerolog kunnen doen.

Eerst moet u het pakket installeren. Als u in deze serie werkt, gebruikt u waarschijnlijk al Go-modules, dus u hoeft niets te doen. In het geval dat u deze opdracht op uw werkstation kunt uitvoeren om de zerolog-bibliotheken te installeren:

go get -u github.com/rs/zerolog/log

Gebruik nu dit codefragment om het te proberen:

package main

import (
    "github.com/rs/zerolog"
    "github.com/rs/zerolog/log"
)

func main() {
    zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
    log.Print("Hey! I'm a log message!")
}

Wanneer u de voorgaande code uitvoert, krijgt u deze uitvoer:

{"level":"debug","time":1609855453,"message":"Hey! I'm a log message!"}

Zoals u ziet, hoeft u alleen de juiste importnamen op te nemen en kunt u de log.Print() functie gewoon blijven gebruiken zoals u dat gewoonlijk doet. U ziet ook hoe de uitvoer wordt gewijzigd in de JSON-indeling. JSON is een handige indeling voor logboeken wanneer u zoekopdrachten uitvoert op een centrale locatie.

Een andere handige functie is dat u snel contextgegevens kunt opnemen, zoals deze:

package main

import (
    "github.com/rs/zerolog"
    "github.com/rs/zerolog/log"
)

func main() {
    zerolog.TimeFieldFormat = zerolog.TimeFormatUnix

    log.Debug().
        Int("EmployeeID", 1001).
        Msg("Getting employee information")

    log.Debug().
        Str("Name", "John").
        Send()
}

Wanneer u de voorgaande code uitvoert, krijgt u deze uitvoer:

{"level":"debug","EmployeeID":1001,"time":1609855731,"message":"Getting employee information"}
{"level":"debug","Name":"John","time":1609855731}

U ziet hoe we als context de werknemer-id hebben toegevoegd. Deze wordt onderdeel van de logboeklijn als een andere eigenschap. Het is ook belangrijk om te benadrukken dat de velden die u opneemt sterk zijn getypt.

U kunt andere functies implementeren met zerolog, zoals het gebruik van gelevelerde logboekregistratie, het gebruik van opgemaakte stacktraceringen en het gebruik van meer dan één logboekregistratie-exemplaar om verschillende uitvoer te beheren. Zie de GitHub-site voor meer informatie.