Skip to content

Instantly share code, notes, and snippets.

@asachs01
Last active January 30, 2024 13:30
Show Gist options
  • Save asachs01/8888e13720e70c9c1c863ee8b7b8e4a8 to your computer and use it in GitHub Desktop.
Save asachs01/8888e13720e70c9c1c863ee8b7b8e4a8 to your computer and use it in GitHub Desktop.
Scripts used for installing Prometheus on Windows & Linux

Aaron's Scripts for Installing the Prometheus Node Exporter, Windows Exporter and Promtail

This is a collection of the scripts that I'm using to install the Prometheus node exporter, Windows exporter and promtail in my hoem lab environments. There are certainly more battle-tested solutions (i.e., the Ansible Prometheus collection is 🤌🤌🤌), but these work well enough to use in small environments. Feel free to use and abuse.

NOTE: Rather than reinventing the wheel on Linux, I'm using https://github.com/carlocorradini/node_exporter_installer to install the node exporter.

NOTE: While yes, Windows does have the ability to create a service natively, I've found that starting the Promtail binary via the natively supported method isn't possible. I'm using WinSW to create a service that will start the Promtail binary.

param (
[string]$hostUrl = $(if ($env:PROMTAIL_HOST_URL) { $env:PROMTAIL_HOST_URL } else { "http://localhost:3100/loki/api/v1/push" }),
[string]$eventTypesStr = $(if ($env:PROMTAIL_EVENT_TYPES) { $env:PROMTAIL_EVENT_TYPES } else { "Application,Security,System" })
)
# Variables
$latestReleaseUrl = "https://github.com/grafana/loki/releases/latest"
$repoUrl = "https://github.com/grafana/loki"
$winswUrl = "https://github.com/winsw/winsw/releases/download/v2.12.0/WinSW-x64.exe"
$outputDir = "C:\"
$promtailDir = "C:\Program Files\Promtail"
# Parse event types and validate
$eventTypes = $eventTypesStr -split ","
$validEventTypes = @("Application", "Security", "System")
foreach ($event in $eventTypes) {
if ($event -notin $validEventTypes) {
throw "Invalid event type specified: $event. Valid event types are 'Application', 'Security', and 'System'."
}
}
# Check and recreate directory if it exists
if (Test-Path $promtailDir) {
Remove-Item $promtailDir -Recurse -Force
}
New-Item -ItemType Directory -Path $promtailDir
# Get the latest release version number from the redirect URL
$redirectedUrl = (Invoke-WebRequest -Uri $latestReleaseUrl -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri
$latestVersion = ($redirectedUrl -split '/tag/')[-1].Trim('/')
# Construct the download URL
$installerName = "promtail-windows-amd64.exe.zip"
$downloadUrl = "$repoUrl/releases/download/$latestVersion/$installerName"
$outputFile = Join-Path -Path $outputDir -ChildPath $installerName
# Download the installer
Write-Host "Now downloading: $downloadUrl"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest -Uri $downloadUrl -OutFile $outputFile
# Remove the previous extracted file if it exists
$extractedFileDestination = Join-Path -Path $outputDir -ChildPath "promtail-windows-amd64.exe"
if (Test-Path $extractedFileDestination) {
Remove-Item $extractedFileDestination -Force
}
# Extract the downloaded zip file
Expand-Archive -Path $outputFile -DestinationPath $outputDir
# Rename and move the extracted file
Rename-Item -Path $extractedFileDestination -NewName "promtail.exe"
Move-Item -Path "$outputDir\promtail.exe" -Destination $promtailDir
# Download WinSW
$winswPath = Join-Path -Path $promtailDir -ChildPath "WinSW.exe"
Invoke-WebRequest -Uri $winswUrl -OutFile $winswPath
# Rename WinSW.exe to match service name
Rename-Item -Path $winswPath -NewName "PromtailService.exe"
$winswPath = Join-Path -Path $promtailDir -ChildPath "PromtailService.exe"
# Create the scrape_configs dynamically based on the event types provided
$scrapeConfigs = @()
foreach ($event in $eventTypes) {
$lowercaseEvent = $event.ToLower()
$scrapeConfig = @"
- job_name: windows_$lowercaseEvent
windows_events:
use_incoming_timestamp: false
bookmark_path: "./bookmark_${lowercaseEvent}_logs.xml"
eventlog_name: "$event"
xpath_query: '*'
labels:
job: windows_$lowercaseEvent
"@
$scrapeConfigs += $scrapeConfig
}
# Create the Promtail configuration file
$configFileContent = @"
server:
http_listen_port: 9080
grpc_listen_port: 0
clients:
- url: $hostUrl
positions:
filename: $promtailDir\positions.yaml
scrape_configs:
$($scrapeConfigs -join "`n")
"@
$configFilePath = Join-Path -Path $promtailDir -ChildPath "promtail-windows.yaml"
$configFileContent > $configFilePath
# Create WinSW configuration
$winswConfigContent = @"
<service>
<id>Promtail</id>
<name>Promtail</name>
<description>Promtail is an agent which ships the contents of local logs to a private Loki instance or Grafana Cloud.</description>
<executable>$promtailDir\promtail.exe</executable>
<arguments>--config.file=`"$configFilePath`"</arguments>
<startmode>Automatic</startmode>
</service>
"@
$winswConfigPath = Join-Path -Path $promtailDir -ChildPath "PromtailService.xml"
$winswConfigContent > $winswConfigPath
# Install and start the service using WinSW
& $winswPath install
& $winswPath start
# Validate the service status
Start-Sleep -Seconds 5 # Giving some time for the service to start
$serviceStatus = (Get-Service "Promtail").Status
if ($serviceStatus -ne 'Running') {
throw "Error: The Promtail service could not be started correctly."
}
# Cleanup: remove downloaded zip file
if (Test-Path $outputFile) {
Remove-Item -Path $outputFile -Force
}
Write-Host "Installation, configuration, and service creation completed!"
# Set TLS and SSL settings
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Fetch the latest release details from GitHub
$latestReleaseUrl = "https://api.github.com/repos/prometheus-community/windows_exporter/releases/latest"
$releaseInfo = Invoke-RestMethod -Uri $latestReleaseUrl
# Construct the download URL based on the tag_name from the release info
$version = $releaseInfo.tag_name.TrimStart('v') # This removes the 'v' prefix
$downloadUrl = "https://github.com/prometheus-community/windows_exporter/releases/download/v$version/windows_exporter-$version-amd64.msi"
$outputFile = "$env:TEMP\windows_exporter-$version-amd64.msi"
# Print the latest release and download URLs
Write-Output "The latest release is: https://github.com/prometheus-community/windows_exporter/releases/tag/v$version"
Write-Output "Now downloading: $downloadUrl"
# Use WebClient to download the MSI installer
$webclient = New-Object System.Net.WebClient
try {
$webclient.DownloadFile($downloadUrl, $outputFile)
} catch {
Write-Error "Failed to download the MSI installer."
exit 1
}
# Install the MSI
Start-Process -Wait -FilePath "msiexec" -ArgumentList "/i `"$outputFile`" /qb"
# Clean up
Remove-Item -Path $outputFile
# Check if the windows_exporter service exists and is running
try {
$service = Get-Service -Name "windows_exporter"
if ($service.Status -eq 'Running') {
Write-Output "windows_exporter service is running."
} else {
Write-Error "windows_exporter service is not running."
exit 1
}
} catch {
Write-Error "windows_exporter service does not exist or there was an error checking its status."
exit 1
}
Write-Output "Installation and verification completed."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment