Files
node_exporter_install/veeam显示其他任务类型版.ps1

243 lines
14 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 完全兼容你的环境,所有原有指标和格式不变
Add-PSSnapin -Name VeeamPSSnapIn -ErrorAction SilentlyContinue
# 配置项
$JobName = "veeam_backup"
$InstanceName = $env:COMPUTERNAME
$OutputFile = Join-Path -Path $PWD.Path -ChildPath "veeam_metrics.prom"
# Linux 上传配置
$linuxUser = "root"
$linuxIP = "10.150.117.190"
$linuxPath = "/opt/prom_textfile/"
$localFile = ".\veeam_metrics.prom"
# 恢复任务采集配置:采集最近多少小时内的恢复会话
$RestoreSessionHours = 24
while ($true) {
$Metrics = @()
$TodayStart = (Get-Date).Date
$GlobalTotalJobs = 0
$GlobalSuccessJobs = 0
$GlobalFailedJobs = 0
$GlobalRunningJobs = 0
$GlobalDailyTotalBackup = 0
# ================== 指标头部(更新包含恢复任务)==================
$Metrics += "# HELP veeam_job_status Veeam all job status (0=Success,1=Warning,2=Failed,3=None)"
$Metrics += "# TYPE veeam_job_status gauge"
$Metrics += "# HELP veeam_job_is_running Veeam job is running (1=running,0=idle)"
$Metrics += "# TYPE veeam_job_is_running gauge"
$Metrics += "# HELP veeam_job_progress_percent Veeam job progress percentage"
$Metrics += "# TYPE veeam_job_progress_percent gauge"
$Metrics += "# HELP veeam_job_backup_size_gb Veeam last job processed size in GB"
$Metrics += "# TYPE veeam_job_backup_size_gb gauge"
$Metrics += "# HELP veeam_job_data_size_gb Veeam last job original data size in GB"
$Metrics += "# TYPE veeam_job_data_size_gb gauge"
$Metrics += "# HELP veeam_job_duration_seconds Veeam last job duration in seconds"
$Metrics += "# TYPE veeam_job_duration_seconds gauge"
$Metrics += "# HELP veeam_job_daily_backup_size_gb Veeam job total processed size today in GB"
$Metrics += "# TYPE veeam_job_daily_backup_size_gb gauge"
$Metrics += "# HELP veeam_repo_free_space_gb Veeam repository free space in GB"
$Metrics += "# TYPE veeam_repo_free_space_gb gauge"
$Metrics += "# HELP veeam_repo_total_space_gb Veeam repository total space in GB"
$Metrics += "# TYPE veeam_repo_total_space_gb gauge"
# 全局统计指标
$Metrics += "# HELP veeam_global_total_jobs Total number of all Veeam jobs"
$Metrics += "# TYPE veeam_global_total_jobs gauge"
$Metrics += "# HELP veeam_global_success_jobs Number of successful Veeam jobs"
$Metrics += "# TYPE veeam_global_success_jobs gauge"
$Metrics += "# HELP veeam_global_failed_jobs Number of failed Veeam jobs"
$Metrics += "# TYPE veeam_global_failed_jobs gauge"
$Metrics += "# HELP veeam_global_running_jobs Number of running Veeam jobs"
$Metrics += "# TYPE veeam_global_running_jobs gauge"
$Metrics += "# HELP veeam_global_daily_total_gb Total processed size of all jobs today in GB"
$Metrics += "# TYPE veeam_global_daily_total_gb gauge"
$Metrics += "# HELP veeam_global_success_rate Overall Veeam job success rate today (0-100)"
$Metrics += "# TYPE veeam_global_success_rate gauge"
# 单任务健康度指标
$Metrics += "# HELP veeam_job_last_success_timestamp Last successful job timestamp (Unix milliseconds)"
$Metrics += "# TYPE veeam_job_last_success_timestamp gauge"
$Metrics += "# HELP veeam_job_since_last_success_hours Hours since last successful job"
$Metrics += "# TYPE veeam_job_since_last_success_hours gauge"
$Metrics += "# HELP veeam_job_compression_ratio Veeam job compression ratio (data_size/backup_size)"
$Metrics += "# TYPE veeam_job_compression_ratio gauge"
# 存储智能预警指标
$Metrics += "# HELP veeam_repo_usage_percent Repository usage percentage (0-100)"
$Metrics += "# TYPE veeam_repo_usage_percent gauge"
$Metrics += "# HELP veeam_repo_remaining_days Estimated remaining days based on daily rate"
$Metrics += "# TYPE veeam_repo_remaining_days gauge"
$Metrics += ""
# ================== 1. 采集所有持久化计划任务 ==================
$Jobs = Get-VBRJob | Where-Object { $_.JobType -in
"Backup", "Restore", "VmRestore", "FileRestore", "Rescan",
"Replication", "BackupCopy", "TapeBackup", "TapeCatalog",
"FileToTape", "SureBackup", "BackupSync", "BackupValidation",
"ConfigurationBackup", "AgentBackup", "AgentRestore",
"NASBackup", "NASRestore", "CloudBackup", "CloudRestore"
}
$AllSessions = Get-VBRBackupSession
$Now = Get-Date # 提前获取当前时间,避免循环中多次调用
# ================== ✅ 新增:采集最近24小时所有恢复会话(手动+计划)==================
$RestoreCutoffTime = $Now.AddHours(-$RestoreSessionHours)
$AllRestoreSessions = Get-VBRRestoreSession | Where-Object { $_.CreationTime -ge $RestoreCutoffTime }
# 将恢复会话转换为统一的任务对象格式
$RestoreTasks = @()
foreach ($Session in $AllRestoreSessions) {
# 跳过已经在计划任务中的恢复任务(去重)
if ($Jobs | Where-Object { $_.Id -eq $Session.JobId }) { continue }
$RestoreTask = [PSCustomObject]@{
Id = $Session.Id
Name = "Restore_" + $Session.Name -replace '[^a-zA-Z0-9_]', '_'
JobType = "RestoreSession"
LastSession = $Session
}
$RestoreTasks += $RestoreTask
}
# 合并计划任务和恢复任务
$AllJobs = $Jobs + $RestoreTasks
$GlobalTotalJobs = $AllJobs.Count
# ================== 统一处理所有任务 ==================
foreach ($Job in $AllJobs) {
# 区分计划任务和临时恢复会话
if ($Job.JobType -eq "RestoreSession") {
$LastSession = $Job.LastSession
} else {
$LastSession = $Job.FindLastSession()
}
$Status = if ($LastSession) { $LastSession.Result } else { "None" }
$State = if ($LastSession) { $LastSession.State } else { "Idle" }
$StatusCode = switch ($Status) {
"Success" { 0; $GlobalSuccessJobs++ }
"Warning" { 1; $GlobalSuccessJobs++ }
"Failed" { 2; $GlobalFailedJobs++ }
default { 3 }
}
$IsRunning = if ($State -eq "Working") { 1; $GlobalRunningJobs++ } else { 0 }
$CleanJobName = $Job.Name -replace '[^a-zA-Z0-9_]', '_' -replace '[\r\n`"''"]', ''
# 基础指标(完全不变)
$Metrics += "veeam_job_status{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $StatusCode"
$Metrics += "veeam_job_is_running{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $IsRunning"
$Metrics += "veeam_job_progress_percent{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $(if($LastSession-and$State-eq'Working'){$LastSession.Progress.Percents}else{0})"
# 任务大小和数据量(兼容恢复会话)
if ($LastSession) {
if ($State -eq "Working") {
$BackupSizeGB = if ($LastSession.Info.Progress.BackupSize) { [math]::Round($LastSession.Info.Progress.BackupSize / 1GB, 2) } else { 0 }
$DataSizeGB = if ($LastSession.Info.Progress.DataSize) { [math]::Round($LastSession.Info.Progress.DataSize / 1GB, 2) } else { 0 }
} else {
$BackupSizeGB = if ($LastSession.BackupStats.BackupSize) { [math]::Round($LastSession.BackupStats.BackupSize / 1GB, 2) } else { 0 }
$DataSizeGB = if ($LastSession.BackupStats.DataSize) { [math]::Round($LastSession.BackupStats.DataSize / 1GB, 2) } else { 0 }
}
$DurationSeconds = if ($LastSession.EndTime -and $LastSession.CreationTime) { [math]::Round(($LastSession.EndTime - $LastSession.CreationTime).TotalSeconds, 2) } else { 0 }
} else {
$BackupSizeGB = 0
$DataSizeGB = 0
$DurationSeconds = 0
}
$Metrics += "veeam_job_backup_size_gb{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $BackupSizeGB"
$Metrics += "veeam_job_data_size_gb{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $DataSizeGB"
$Metrics += "veeam_job_duration_seconds{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $DurationSeconds"
# 当日任务量(包含恢复任务)
$TodaySessions = $AllSessions | Where-Object { $_.JobId -eq $Job.Id -and $_.CreationTime -ge $TodayStart }
$DailyBackupSizeGB = 0
foreach ($Session in $TodaySessions) {
if ($Session.BackupStats.BackupSize) {
$DailyBackupSizeGB += $Session.BackupStats.BackupSize / 1GB
}
}
$DailyBackupSizeGB = [math]::Round($DailyBackupSizeGB, 2)
$GlobalDailyTotalBackup += $DailyBackupSizeGB
$Metrics += "veeam_job_daily_backup_size_gb{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $DailyBackupSizeGB"
# 任务健康度指标(兼容恢复会话)
if ($Job.JobType -eq "RestoreSession") {
# 恢复会话直接使用当前会话作为最后成功会话
$LastSuccessSession = if ($Status -eq "Success") { $LastSession } else { $null }
} else {
$JobSuccessSessions = $AllSessions | Where-Object { $_.JobId -eq $Job.Id -and $_.Result -eq "Success" } | Sort-Object EndTime -Descending
$LastSuccessSession = $JobSuccessSessions | Select-Object -First 1
}
if ($LastSuccessSession -and $LastSuccessSession.EndTime) {
$LastSuccessTimestamp = [math]::Round($LastSuccessSession.EndTime.ToUniversalTime().Subtract((Get-Date "1970-01-01")).TotalMilliseconds, 0)
$TimeDiff = ($Now) - $LastSuccessSession.EndTime
$SinceLastSuccessHours = [math]::Round($TimeDiff.TotalHours, 1)
} else {
$LastSuccessTimestamp = 0
$SinceLastSuccessHours = 9999
}
$Metrics += "veeam_job_last_success_timestamp{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $LastSuccessTimestamp"
$Metrics += "veeam_job_since_last_success_hours{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $SinceLastSuccessHours"
# 压缩率(恢复任务压缩率为0
$CompressionRatio = if ($BackupSizeGB -gt 0) { [math]::Round($DataSizeGB / $BackupSizeGB, 2) } else { 0 }
$Metrics += "veeam_job_compression_ratio{job=`"$JobName`",instance=`"$InstanceName`",job_name=`"$CleanJobName`"} $CompressionRatio"
}
# 全局统计(完全不变)
$GlobalSuccessRate = if ($GlobalTotalJobs -gt 0) { [math]::Round(($GlobalSuccessJobs / $GlobalTotalJobs) * 100, 1) } else { 0 }
$Metrics += "veeam_global_total_jobs{job=`"$JobName`",instance=`"$InstanceName`"} $GlobalTotalJobs"
$Metrics += "veeam_global_success_jobs{job=`"$JobName`",instance=`"$InstanceName`"} $GlobalSuccessJobs"
$Metrics += "veeam_global_failed_jobs{job=`"$JobName`",instance=`"$InstanceName`"} $GlobalFailedJobs"
$Metrics += "veeam_global_running_jobs{job=`"$JobName`",instance=`"$InstanceName`"} $GlobalRunningJobs"
$Metrics += "veeam_global_daily_total_gb{job=`"$JobName`",instance=`"$InstanceName`"} $([math]::Round($GlobalDailyTotalBackup, 2))"
$Metrics += "veeam_global_success_rate{job=`"$JobName`",instance=`"$InstanceName`"} $GlobalSuccessRate"
$Metrics += ""
# ================== 2. 存储库指标(完全不变)==================
$Repositories = Get-VBRBackupRepository
foreach ($Repo in $Repositories) {
$Path = $Repo.Path
$DriveLetter = (Split-Path $Path -Qualifier).TrimEnd(':')
$DiskInfo = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='$DriveLetter`:'" -ErrorAction SilentlyContinue
$FreeSpaceGB = if ($DiskInfo -and $DiskInfo.FreeSpace) { [math]::Round($DiskInfo.FreeSpace / 1GB, 2) } else { 0 }
$TotalSpaceGB = if ($DiskInfo -and $DiskInfo.Size) { [math]::Round($DiskInfo.Size / 1GB, 2) } else { 0 }
$CleanRepoName = $Repo.Name -replace '[^a-zA-Z0-9_]', '_' -replace '[\r\n`"''"]', ''
$Metrics += "veeam_repo_free_space_gb{job=`"$JobName`",instance=`"$InstanceName`",repo_name=`"$CleanRepoName`"} $FreeSpaceGB"
$Metrics += "veeam_repo_total_space_gb{job=`"$JobName`",instance=`"$InstanceName`",repo_name=`"$CleanRepoName`"} $TotalSpaceGB"
# 存储使用率和剩余天数
$UsagePercent = if ($TotalSpaceGB -gt 0) { [math]::Round((($TotalSpaceGB - $FreeSpaceGB) / $TotalSpaceGB) * 100, 1) } else { 0 }
$Metrics += "veeam_repo_usage_percent{job=`"$JobName`",instance=`"$InstanceName`",repo_name=`"$CleanRepoName`"} $UsagePercent"
$RemainingDays = if ($GlobalDailyTotalBackup -gt 0 -and $FreeSpaceGB -gt 0) { [math]::Round($FreeSpaceGB / $GlobalDailyTotalBackup, 1) } else { 999 }
$Metrics += "veeam_repo_remaining_days{job=`"$JobName`",instance=`"$InstanceName`",repo_name=`"$CleanRepoName`"} $RemainingDays"
}
# ================== 格式保证 & 上传(完全不变)==================
$Metrics += ""
$MetricsBody = $Metrics -join "`n" -replace "`r", ""
[System.IO.File]::WriteAllText($OutputFile, $MetricsBody, [System.Text.UTF8Encoding]::new($false))
Write-Host "`n📤 正在上传指标文件..." -ForegroundColor Cyan
scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=NUL $localFile "${linuxUser}@${linuxIP}:${linuxPath}"
if ($LASTEXITCODE -eq 0) {
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=NUL "${linuxUser}@${linuxIP}" "sed -i 's/\r$//;s/[^[:print:]]//g' ${linuxPath}veeam_metrics.prom && chmod 644 ${linuxPath}veeam_metrics.prom"
Write-Host "✅ [$((Get-Date).ToString('yyyy-MM-dd HH:mm:ss'))] 采集完成"
Write-Host " - 总任务: $GlobalTotalJobs | 成功: $GlobalSuccessJobs | 失败: $GlobalFailedJobs | 运行中: $GlobalRunningJobs"
Write-Host " - 今日总处理量: $([math]::Round($GlobalDailyTotalBackup, 2)) GB | 成功率: $GlobalSuccessRate%"
Write-Host " - 已包含计划任务+最近$RestoreSessionHours小时恢复任务,等待60秒`n" -ForegroundColor Green
} else {
Write-Host "❌ 上传失败,请检查SSH免密配置" -ForegroundColor Red
}
Start-Sleep -Seconds 60
}