audit: build plugin usage matrix from logs
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
param(
|
||||
[string]$Source = 'C:\dev\TEMP\Reports',
|
||||
[string]$Output = 'C:\dev\autodesk\migration\audits\plugin-usage-matrix-20260731'
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$utf8 = New-Object System.Text.UTF8Encoding($false)
|
||||
$outputEvidence = Join-Path $Output 'evidence'
|
||||
New-Item -ItemType Directory -Force -Path $outputEvidence | Out-Null
|
||||
|
||||
# The source is read only. Only the three fields captured below are emitted.
|
||||
$pattern = '^.*?\s+(?<plugin>\S+)\s+(?<internal_code>\S+)\s+(?<time>\d{2}:\d{2}:\d{2})\s+(?<date>\d{2}\.\d{2}\.\d{2,4})\s+(?<computer>\S+)\s*$'
|
||||
$records = [System.Collections.Generic.List[object]]::new()
|
||||
$fileCount = 0
|
||||
$lineCount = 0
|
||||
$blankCount = 0
|
||||
$unmatchedCount = 0
|
||||
|
||||
foreach ($file in (Get-ChildItem -LiteralPath $Source -Recurse -File | Sort-Object FullName)) {
|
||||
$fileCount++
|
||||
foreach ($line in Get-Content -LiteralPath $file.FullName -Encoding UTF8) {
|
||||
$text = $line.Trim()
|
||||
if ([string]::IsNullOrWhiteSpace($text)) { $blankCount++; continue }
|
||||
$lineCount++
|
||||
if ($text -notmatch $pattern) { $unmatchedCount++; continue }
|
||||
$dateText = $matches.date
|
||||
$format = if ($dateText.Length -eq 8) { 'dd.MM.yy' } else { 'dd.MM.yyyy' }
|
||||
$date = [DateTime]::ParseExact(($dateText + ' ' + $matches.time), ($format + ' HH:mm:ss'), [Globalization.CultureInfo]::InvariantCulture, [Globalization.DateTimeStyles]::None)
|
||||
$records.Add([pscustomobject]@{
|
||||
plugin_name = $matches.plugin
|
||||
launch_timestamp = $date.ToString('yyyy-MM-ddTHH:mm:ss', [Globalization.CultureInfo]::InvariantCulture)
|
||||
computer_name = $matches.computer
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
$unique = $records | Sort-Object plugin_name,launch_timestamp,computer_name -Unique
|
||||
$unique | Export-Csv (Join-Path $Output 'plugin-usage-matrix.csv') -NoTypeInformation -Encoding UTF8
|
||||
|
||||
$summary = $unique | Group-Object plugin_name | Sort-Object Name | ForEach-Object {
|
||||
$items = $_.Group | Sort-Object launch_timestamp,computer_name
|
||||
[pscustomobject]@{
|
||||
plugin_name = $_.Name
|
||||
unique_launches = $items.Count
|
||||
unique_computers = ($items.computer_name | Sort-Object -Unique).Count
|
||||
first_launch_timestamp = $items[0].launch_timestamp
|
||||
last_launch_timestamp = $items[-1].launch_timestamp
|
||||
}
|
||||
}
|
||||
$summary | Export-Csv (Join-Path $Output 'plugin-usage-summary.csv') -NoTypeInformation -Encoding UTF8
|
||||
|
||||
$diagnostics = @(
|
||||
'Input format: one record per non-empty line; only plugin, timestamp and computer fields are retained.',
|
||||
('Input files: ' + $fileCount),
|
||||
('Non-empty input records: ' + $lineCount),
|
||||
('Blank input lines ignored: ' + $blankCount),
|
||||
('Unmatched non-empty records: ' + $unmatchedCount),
|
||||
('Parsed records: ' + $records.Count),
|
||||
('Unique three-attribute records: ' + $unique.Count),
|
||||
('Unique plugins: ' + (($unique.plugin_name | Sort-Object -Unique).Count)),
|
||||
('Date normalization: dd.MM.yy and dd.MM.yyyy to yyyy-MM-ddTHH:mm:ss'),
|
||||
'Sort order: plugin_name, launch_timestamp, computer_name.',
|
||||
'Project numbers, project names, project paths and source log filenames are intentionally excluded.'
|
||||
)
|
||||
[IO.File]::WriteAllLines((Join-Path $outputEvidence 'parse-diagnostics.txt'), $diagnostics, $utf8)
|
||||
Reference in New Issue
Block a user