Info
Logging er en universell ferdighet som gjelder alle programmeringsspråk og rammeverk! Konseptene du lærer her kan du ta med deg til Java, JavaScript, C#, Go, Rust - you name it. Vi bruker Python som hovedeksempel, men prinsippene er de samme overalt. 🌍
Hvorfor logging? 🤔
Har du noen gang brukt print() for å finne ut hva som skjer i programmet ditt? Det fungerer kanskje greit når du sitter og koder alene, men hva skjer når programmet kjører på en server? Eller når du skal feilsøke noe som skjedde i går? Da trenger du noe bedre enn print() - da trenger du logging! 📋
Del 1 - Hva er Logging?
Logging handler om å skrive ned hva et program gjør mens det kjører. Tenk på det som en dagbok for programmet ditt. Hver gang noe viktig skjer - en bruker logger inn, en feil oppstår, en beregning fullføres - så skriver programmet en logg-melding.
Hvorfor ikke bare bruke print()?
La oss sammenligne:
print() | logging | |
|---|---|---|
| Nivåer (info, error, debug) | ❌ | ✅ |
| Tidsstempel | ❌ | ✅ |
| Skrive til fil | ❌ | ✅ |
| Slå av/på enkelt | ❌ | ✅ |
| Bruke i produksjon | ❌ | ✅ |
| Filtrere meldinger | ❌ | ✅ |
Med andre ord: print() er greit for rask debugging, men logging er det profesjonelle valget! 💼
Logging-nivåer
De fleste logging-systemer (uansett språk!) har disse nivåene, fra minst til mest alvorlig:
| Nivå | Beskrivelse | Eksempel |
|---|---|---|
DEBUG | Detaljert info, mest for feilsøking | “Bruker sendte request med data: {…}” |
INFO | Generell info om at ting fungerer | “Server startet på port 8000” |
WARNING | Noe uventet, men programmet kjører fortsatt | “Disk er 90% full” |
ERROR | Noe gikk galt | “Kunne ikke koble til database” |
CRITICAL | Alvorlig feil, programmet kan kræsje | “Ut av minne, avslutter” |
Tommelfingerregel 👍
DEBUG- Ting du bare trenger under utviklingINFO- Ting du vil vite om i produksjonWARNING- Ting som kanskje blir et problemERROR- Ting som er et problemCRITICAL- Ting som er et STORT problem
Del 2 - Python sin logging-modul
Python har en innebygd modul som heter logging. Den trenger ikke installeres - den følger med Python!
Her er et grunnleggende eksempel:
import logging
# Sett opp grunnleggende logging
logging.basicConfig(level=logging.DEBUG)
# Lag en logger
logger = logging.getLogger(__name__)
# Bruk de forskjellige nivåene
logger.debug("Dette er en debug-melding")
logger.info("Serveren startet!")
logger.warning("Pass på, disken er nesten full!")
logger.error("Kunne ikke koble til databasen!")
logger.critical("Alt har gått galt! 💀")
Hva er __name__?
__name__ er en spesiell variabel i Python som inneholder navnet på den nåværende modulen. Hvis du kjører filen direkte, vil __name__ være "__main__". Hvis filen importeres fra en annen fil, vil den ha filnavnet.
Dette er nyttig fordi du kan se hvilken fil en logg-melding kommer fra! 🔍
Del 3 - Et eksempel i et annet språk
Bare for å vise at logging er universelt - her er det samme konseptet i JavaScript (Node.js):
// JavaScript bruker ofte 'console' som en enkel logger
console.debug("Debug-melding");
console.info("Info-melding");
console.warn("Advarsel!");
console.error("Feil!");
// Men i produksjon bruker man gjerne et bibliotek som 'winston' eller 'pino'
Og i Java:
import java.util.logging.Logger;
Logger logger = Logger.getLogger("MinApp");
logger.info("Serveren startet!");
logger.warning("Noe rart skjedde...");
logger.severe("Kritisk feil!"); // Java bruker "severe" istedenfor "critical"
Legg merke til at konseptene er nesten identiske - det er bare syntaksen som er forskjellig! 😎
Oppgaver
Oppgave 1.1 - Første Logger
Lag et Python-program som bruker logging-modulen til å logge meldinger på alle fem nivåer.
- Importer
logging - Sett opp
basicConfigmedlevel=logging.DEBUG - Lag en logger med
getLogger() - Logg en melding på hvert nivå (
debug,info,warning,error,critical) - Kjør programmet og se hva som skrives ut i terminalen
Hva bør outputen se ut som?
Du bør se noe sånt som:
DEBUG:__main__:Dette er en debug-melding
INFO:__main__:Server startet
WARNING:__main__:Advarsel!
ERROR:__main__:Noe gikk galt
CRITICAL:__main__:Alt kræsjet!
Oppgave 1.2 - Endre nivå
Prøv å endre level i basicConfig til logging.WARNING.
- Hva skjer med
debugoginfomeldingene? - Hvorfor er dette nyttig?
Svar
Når du setter nivået til WARNING, vil bare meldinger på WARNING, ERROR og CRITICAL vises. DEBUG og INFO meldingene blir filtrert bort. Dette er nyttig fordi du kan ha masse debug-meldinger i koden som kun vises når du trenger dem, uten å “rote til” output i produksjon!
Oppgave 1.3 - Logging med kontekst
Lag et lite program med en funksjon som deler to tall. Bruk logging til å:
- Logge på
DEBUG-nivå hva tallene er - Logge på
INFO-nivå hva resultatet er - Logge på
ERROR-nivå dersom brukeren prøver å dele på null
Tips
Bruk try/except for å fange ZeroDivisionError. Du kan bruke f-strings i logg-meldinger:
logger.debug(f"Deler {a} på {b}")
Eksempel på løsning
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
def divide(a, b):
logger.debug(f"Forsøker å dele {a} på {b}")
try:
result = a / b
logger.info(f"Resultat: {a} / {b} = {result}")
return result
except ZeroDivisionError:
logger.error(f"Kan ikke dele {a} på null!")
return None
divide(10, 2)
divide(10, 0)
Oppgave 1.4 - Logging til fil
Nå skal vi skrive loggen til en fil i tillegg til terminalen! Endre basicConfig til å inkludere en filename:
logging.basicConfig(
level=logging.DEBUG,
filename="app.log",
filemode="w", # "w" = overskriv, "a" = legg til
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
- Kjør programmet ditt fra forrige oppgave med denne konfigurasjonen
- Åpne
app.logog se hva som står der - Hva gjør
format-parameteren? Prøv å endre den!
Merk!
Når du setter filename vil meldingene kun skrives til filen, ikke til terminalen. I neste level skal vi se på hvordan vi kan gjøre begge deler! 🔥