🎓 A1Learner
🔍
0 of 47 lessons completed

PowerShell Project: Log Analyzer

A log analyzer is a script that reads a log file and counts its messages by level. It turns many lines of text into one short summary.

Create a small fixed log file

The script first creates the log it will read. Every run uses the same five lines, so every run gives the same result.

$logPath = Join-Path $PSScriptRoot "app.log"
Set-Content -Path $logPath -Value @(
    "INFO: Started the service",
    "WARN: Disk space is low",
    "ERROR: Failed to save the file",
    "INFO: Retried the save",
    "ERROR: Connection timed out"
)
$lines = Get-Content -Path $logPath
"Lines: $($lines.Count)"
($lines -join " | ")

Parse each line into level and message

A pattern splits each line into its level and its message. The script prints both parts for every line.

$logPath = Join-Path $PSScriptRoot "app.log"
Set-Content -Path $logPath -Value @(
    "INFO: Started the service",
    "WARN: Disk space is low",
    "ERROR: Failed to save the file",
    "INFO: Retried the save",
    "ERROR: Connection timed out"
)
$lines = Get-Content -Path $logPath
foreach ($line in $lines) {
    if ($line -match "^(INFO|WARN|ERROR): (.*)$") {
        "$($Matches[1]) => $($Matches[2])"
    }
}

Count by level and collect the errors

Counters grow as each level is found. Error messages are collected so the summary can print them together.

$logPath = Join-Path $PSScriptRoot "app.log"
Set-Content -Path $logPath -Value @(
    "INFO: Started the service",
    "WARN: Disk space is low",
    "ERROR: Failed to save the file",
    "INFO: Retried the save",
    "ERROR: Connection timed out"
)
$lines = Get-Content -Path $logPath
$infoCount = 0
$warnCount = 0
$errorCount = 0
$errors = @()
foreach ($line in $lines) {
    if ($line -match "^(INFO|WARN|ERROR): (.*)$") {
        if ($Matches[1] -eq "INFO") { $infoCount++ }
        elseif ($Matches[1] -eq "WARN") { $warnCount++ }
        else { $errorCount++; $errors += $Matches[2] }
    }
}
"INFO: $infoCount"
"WARN: $warnCount"
"ERROR: $errorCount"
"Errors: " + ($errors -join "; ")

Example

$logPath = Join-Path $PSScriptRoot "app.log"
Set-Content -Path $logPath -Value @(
    "INFO: Started the service",
    "WARN: Disk space is low",
    "ERROR: Failed to save the file",
    "INFO: Retried the save",
    "ERROR: Connection timed out"
)
$lines = Get-Content -Path $logPath
$infoCount = 0
$warnCount = 0
$errorCount = 0
$errors = @()
foreach ($line in $lines) {
    if ($line -match "^(INFO|WARN|ERROR): (.*)$") {
        if ($Matches[1] -eq "INFO") { $infoCount++ }
        elseif ($Matches[1] -eq "WARN") { $warnCount++ }
        else { $errorCount++; $errors += $Matches[2] }
    }
}
"Log Summary"
"INFO: $infoCount"
"WARN: $warnCount"
"ERROR: $errorCount"
"Errors: " + ($errors -join "; ")

Key points

  • Log line: one line that records one event with a level and a message.
  • Level: a short label such as INFO, WARN, or ERROR that shows how serious an event is.
  • Use -match to test a line against a pattern and capture its parts.
  • Use $Matches[1] for the first captured part and $Matches[2] for the second part.
  • Use a counter variable to count lines of each level as the script reads them.
  • Summary: one short report that shows each count and the error messages together.

In this example, the script creates a fixed log file and reads it line by line. It matches each line to capture the level and the message, counts each level, and collects the error messages. It then prints a fixed-format summary with the three counts and the error messages joined together.

Note

a log file read by Get-Content gives one line at a time in file order.

Try it Yourself

Edit the code, then press Run.

Running is simulated

Exercise

Which pattern captures the level and the message from a line such as "ERROR: Failed to save the file"?