i vår ”Komma igång med loggning” – serie har vi redan täckt loggning för många språk och ramar: C#, Java, Python, Ruby, Ruby on Rails, Node.js, Symfony, Kotlin, kolv, vinkel och Laravel. Idag lägger vi till en annan i denna serie: PowerShell.
det kan vara en udda att lägga till i listan; PowerShell är ett skriptspråk, medan de andra kan ses som fullständiga programmeringsspråk eller ramar för program., Ändå PowerShell är så tillräckligt kraftfull att den kan skapa system komplexa och viktiga nog att motivera loggning.
PowerShell används ofta för att utföra kritiska underhållsuppgifter på datorer eller servrar. Det är viktigt för administratörer att veta hur om dessa skript sprang bra eller inte.
vi ska undersöka hur du kan logga med PowerShell på ett mycket grundläggande sätt genom att skriva din egen loggningsfunktion. Då täcker vi varför loggning från PowerShell är användbar. Vi pratar också om vad du ska logga och vad du inte ska logga in., Slutligen tittar vi på två olika alternativ som gör dina loggningsliv enklare.
ett enkelt PowerShell-skript
låt oss börja med det här extremt enkla PowerShell-skriptet:
det här grundläggande skriptet tar ett heltal som inmatning. Det gör sedan summan av siffrorna i det numret. Om resultatet är längre än en enda siffra, utför det operationen igen tills detta resulterar i en enda siffra.,
här är några exempel för att klargöra saker:
- 45 – > 4 + 5 = 9
- 397 – > 3 + 9 + 7 = 19 -> 1 + 9 = 10 -> 1 + 0 = 1
- 3 -> 3
lägg det här skriptet i en textfil och spara det som recursiveSum.ps1. sedan kan du köra det på PowerShell kommandoraden genom att köra recursiveSum.ps1 45, till exempel., Utgången kommer att vara 9:
detta är ett skript som är enkelt att fungera som ett exempel men har tillräckligt med steg för att vi skulle kunna vara intresserade av viss loggning. Självklart kommer verkliga PowerShell-skript att vara mycket mer komplexa, vilket garanterar behovet av loggning ännu mer.
det enklaste sättet att logga in PowerShell
låt oss skriva resultatet av varje steg till konsolen. Vi skriver redan något till konsolen genom att använda skrivutmatningen, så vi kan enkelt använda det igen., Ändra while loop för att inkludera ett sådant uttalande:
När du kör det nu bör du kunna se en utgång så här:
det är bra! Vi har lite loggning på gång. Dessa loggangivelser kommer dock alltid att vara synliga. I ett mer komplext program kan det vara meningsfullt att visa ingenting om inte användaren vill se loggningen. Det är förmodligen också användbart att ge användaren viss kontroll över hur mycket detalj de ser. Det är där log nivåer kommer in.,
Log nivåer i PowerShell
PowerShell har några skriv – * uttalanden som karta till traditionella log nivåer som:
- skriv-Verbose
- skriv-Debug
- skriv-Information
- skriv-Varning
- skriv-fel
Verbose
låt oss titta på Skriv-Verbose först. Vi kan ändra våra meddelanden om de mellanliggande stegen för att använda Skriv Verbose., När vi kör vårt manus nu ser vi inte våra mellanliggande steg:
men om vi lägger till-Verbose-flaggan visas våra loggar igen:
och om vi vill dölja varningarna, kan vi använda warningaction silentlyfortsätt alternativet:
fel
slutligen, låt oss titta på hur skrivfel fungerar., Vi kan lägga till ett sådant uttalande till vårt manus:
Write-Error "Something went wrong"
När detta uttalande körs kommer PowerShell att stoppa utförandet av vårt manus och skriva felet till konsolen, tillsammans med några detaljer som kan vara användbara:
vad är programloggning?
Låt oss nu ta ett steg bort från vårt PowerShell-skript och titta på vilken programloggning som är exakt., Det första inlägget i vår serie definierade det bra:
Programloggning innebär att du spelar in information om programmets runtime-beteende till ett mer beständigt medium.
vi gör redan den första delen: med andra ord, fånga information om vår ansökan runtime beteende. Vi visar de mellanliggande resultaten av vår process. Men vi gör inte den andra delen. Vi spelar inte in den här informationen till ett ihållande medium. När vi stänger vår PowerShell session, vi har förlorat denna information. Låt oss göra det först.,
logga in i en fil
Vi lägger till den här loggfunktionen i vår skriptfil:
Function Log { param( $msg ) Add-Content log.txt $msg}
den tar bara in en sträng och lägger sedan till den i en logg.txt-filen.,
då kan vi ändra vårt loggutdrag så att det inte längre använder Skriv Verbose men den här loggfunktionen istället:
Log "Intermediate result: $($sum)"
Nu kan vi köra vårt skript och det kommer att skapa en fil som innehåller våra mellanliggande steg:
men om vi kör vårt skript flera gånger kommer det bara att vara en lång lista med uttalanden. Vi vet inte när linjerna loggades. I ett mer komplext scenario, som innehåller flera skript, har vi inte heller något sätt att veta var logglinjen härstammar—dvs,, från vilken ps1 fil. Det finns mer information som vi kan logga.
igen, låt oss ta ett steg tillbaka och titta på vad vi försöker uppnå med loggning.
varför loggar vi?
PowerShell används ofta för att automatisera och skript vissa uppgifter som annars skulle vara tråkiga och felbenägna. Automatisering börjar verkligen ge värde när det tillämpas på mer komplexa uppgifter. Men dessa komplexa skript kan också ha större chans att bryta: tjänster kanske inte svarar, maskinkonfigurationer kan ha ändrats etc.,
utan loggning är det svårt att veta om skript gick bra eller om något gick fel. Om något gick fel, loggning hjälper oss att ta reda på var och varför det gjorde. Programloggning kan också hjälpa dig att samla insikter i vilka delar av dina skript som används mest eller där prestandavinster fortfarande kan göras.
Vad ska du inte logga in?
När du skriver dina loggningsuppgifter, se till att du lämnar ut känsliga eller personuppgifter., Exempel är:
- lösenord och åtkomsttokens
- kreditkortsnummer eller bankkontonummer
- personnummer
- e-postadresser
- gatuadresser
- krypteringsnycklar
- personnummer
OWASP cheat sheet vid loggning har ett avsnitt om data för att utesluta det är intressant att läsa. Även om det syftar till fullfjädrade applikationer kan det vara användbart för PowerShell-skript också. Jag kan föreställa mig scenarios där PowerShell-skript hanterar e-postadresser eller vissa API-nycklar.,
loggning av sådan personligt identifierbar information (eller PII) är farlig. Inte bara behöver du uttryckligt samtycke från användaren i de flesta länder, men om uppgifterna någonsin läckt, kan du eller ditt företag hållas ansvariga. Om det inte är nödvändigt är det bättre att lämna dessa data ut.
Vad ska du logga?
vår artikel om att komma igång med Ruby loggning gör en stor punkt:
Du bör tänka på en loggpost som en händelse—något som är av intresse för din app som hände någon gång.,
detta innebär att vi åtminstone behöver en tidsstämpel och en beskrivning av händelsen. Beskrivningen kan också innehålla relevanta uppgifter. Detta är inte alltid lätt att bestämma i förskott. Tänk på vad du skulle behöva felsöka ett skript som misslyckades med att köra framgångsrikt. Och om du senare stöter på en situation där du skulle ha krävt mer information för att åtgärda ett problem, lägg till det i loggningen för nästa gång.,
mindre uppenbart, men mycket användbart, är att inkludera en loggnivå:
- på lägsta nivå kan Felsökningsutdrag vara användbara för att spåra det exekverade flödet av ditt PowerShell-skript.
- en nivå upp är informativa meddelanden om den funktionella sidan av ditt skript: vad utfördes, varför och med vilka data?
- då finns det också nivån på varningar: saker som inte är normala och potentiellt skadliga men som inte hindrar skriptet från att fortsätta.
- slutligen finns felnivåmeddelanden där för att logga fel som har gjort skriptkraschen.,
Du kan välja att logga alla dessa nivåer eller bara en viss nivå och uppåt (till exempel varningar och fel). Sedan, när du behöver mer information, kan du konfigurera ditt skript för att också logga mer information om nästa utförande.
vår egen enkla loggningsfunktion inkluderade inte loggnivåer. Inte heller lade det till en tidsstämpel. Vi kan naturligtvis lägga till denna funktionalitet, men lyckligtvis har andra redan skapat anständiga loggningsskript.
skriv in Loggningsskriptet
det finns ett enkelt men användbart skript på Technet som heter Write-Log., Om vi laddar ner det kan vi ändra vårt skript för att se ut så här:
Vi har inkluderat filen Function-Write-Log.ps1, tagit bort vår loggfunktion och ersatt samtalet med ett samtal för att skriva-Log. Vi kan skicka ett meddelande, en nivå och en väg. Nivån kan vara Info, Varna eller fel. Observera att det här skriptet inte har en Felsökningsnivå, vilket är olyckligt. Du kan dock enkelt ändra det för att inkludera det, eftersom skriptet släpps under MIT-licensen tillåter modifiering.,
När vi använder det här skriptet kommer vår logg att se ut så här:
2019-08-20 09:18:29 INFO: Intermediate result: 512019-08-20 09:18:29 INFO: Intermediate result: 6
Vi har nu tydliga logglinjer som inkluderar en tidsstämpel, loggnivån och vårt meddelande. Det är mycket bättre än vad vi hade tidigare. Detta kan vara tillräckligt för dina behov, men låt oss ta det ett steg längre och titta på ett annat alternativ: Psframen.
ange Loggningsramen
PSFramework är ett PowerShell-ramverk som innehåller flera användbara verktyg. Vi ska bara titta på loggningsdelen.,
för att komma igång med PSFramework måste du först installera det genom att köra Install-Module PSFramework i PowerShell. (Du kanske måste köra PowerShell-konsolen som administratör). Sedan kan du skriva till loggfilerna genom att ringa skriv-psfmessage script. I vårt fall skulle det se ut så här:
Write-PSFMessage -Level Output -Message "Intermediate result: $($sum)"
Lägg märke till hur vi inte använder en informationsnivå. Istället använder vi utgång. Detta beror på att psframework använder loggnivåer som matchar mer snyggt med de olika utdataströmmarna som PowerShell har som standard: Verbose, Host, Output, Warning, Error, etc.,
loggfilen kommer också att se lite annorlunda ut än vad vi är vana vid:
kolumnrubrikerna saknas, men det kan enkelt åtgärdas genom att ange loggleverantören först:
den här loggfilen kommer att innehålla en tidsstämpel i filnamnet och kommer nu att innehålla en rubrikrad. Detta beror på att psframeworks standardloggleverantör inte lägger till en rubrikrad, men logfile-leverantören kommer., Loggfilen kommer nu att se ut så här:
det här innehåller nu mycket användbar information som filnamnet på vårt skript, raden där loggningen inträffade och användarnamnet för användaren som kör skriptet. En annan stor fördel med loggningen av PSFramework är att den loggar asynkront. Loggningen kommer inte att sakta ner dina skript. Slutligen kommer det också automatiskt rensa upp dina loggar. Som standard kommer det att ta bort loggfiler efter sju dagar eller när de överstiger 100 megabyte.,
en jämförelse
skriptet Function-Write-Log matchar mer med vad många applikationsprogrammerare används till. Den innehåller standardloggnivåerna (förutom Debug) och skriver en loggfil som många loggningsramar gör: en tidsstämpel, loggnivån och meddelandet.
det saknar dock några extra funktioner som kan vara avgörande för dig: logga städa upp; asynkron loggning; och extra teknisk information som manus, radnummer och verkställande användare.,
psframework loggning ger dessa funktioner, men det kräver att du installerar hela ramen. Detta borde inte vara ett verkligt problem, men det är något att komma ihåg. PSFramework använder också olika loggningsnivåer än vi är vana vid. De matchar dock nära PowerShell – utmatningsströmmarna. Detta kan känna sig mer naturligt för erfarna PowerShell-användare.
vad händer härnäst?
Vi har tagit en titt på ett enkelt sätt att logga in PowerShell. Vi förbättrade också vår egen lösning genom att använda ett bättre skript (Function-Write-Log.ps1) och genom att använda loggningen som ingår i PSFramework.,
en sak som slog mig var att logga in PowerShell fortfarande är ganska grundläggande. Det är inte så att alternativen vi tittade på är dåliga eller saknas. Men jag hittade inte ett enda loggningsskript eller en modul som innehåller flera loggnivåer, asynkron loggning, log clean up och, viktigast av allt, flera loggdestinationer.
vad händer om vi vill skicka fel till en e-postadress? Eller vad händer om vi vill logga in i en databas? Såvitt jag kan se erbjuder PSFramework flest alternativ här, men e-post eller databas ingår inte. Det kan dock vara möjligt att skriva din egen och registrera den i PSFramework.,
detta kan bero på att Powershells värld är annorlunda än applikationsutvecklingsvärlden. PowerShell-skript kan vara mycket mer skräddarsydda, avsedda för ett visst scenario, och består av flera separata skript.
men loggning är fortfarande viktigt, särskilt med skript som körs regelbundet och har en viss grad av komplexitet. PowerShell är ett kraftfullt språk för att automatisera en mängd uppgifter. När något går fel med en sådan uppgift vill du veta vad som gick fel, vad som föregick det och hur man fixar det. Loggar ger dig denna information.,
som nästa steg upp kanske du vill titta på aggregera och hantera dina loggar. Scalyr är ett bra verktyg för detta. Titta på Scalyr API för de olika alternativen för att skicka logghändelser till Scalyr. Detta kan enkelt kallas från PowerShell och kommer att förbättra din förmåga att övervaka och felsöka dina PowerShell skript.
det här inlägget skrevs av Peter Morlion., Peter är en passionerad programmerare som hjälper människor och företag att förbättra kvaliteten på deras kod, särskilt i äldre kodbaser. Han är övertygad om att branschens bästa praxis är ovärderlig när man arbetar mot detta mål, och hans specialiteter inkluderar TDD, DI och solida principer.
Lämna ett svar