Add Prometheus setup for Windows: implement playbook, tasks, and Grafana dashboard configuration

This commit is contained in:
2025-10-03 21:56:31 +02:00
parent cd69dbc25a
commit 7cad175406
7 changed files with 803 additions and 159 deletions
@@ -9,3 +9,21 @@ game_user: "GameUser"
game_password: "{{ lookup('env', 'WIN_GAME_PASSWORD') }}"
game_default_groups:
- Administradores # This is mandatory to install games
grafana_prometheus_sources:
- 10.19.4.136
windows_exporter_collectors:
- cache
- cpu
- cpu_info
- gpu
- diskdrive
- logical_disk
- memory
- net
- os
- process
- service
- tcp
- time
- update
+1 -1
View File
@@ -2,6 +2,6 @@
hosts: windows_game
tasks:
- name: Setup WakeOnLan
- name: Setup Optimizations
ansible.builtin.include_tasks:
file: tasks/windows_game.yml
+7
View File
@@ -0,0 +1,7 @@
- name: Setup Prometheus on Windows
hosts: windows_prometheus
tasks:
- name: Setup Prometheus
ansible.builtin.include_tasks:
file: tasks/windows_prometheus.yml
+2
View File
@@ -4,3 +4,5 @@ collections:
- community.general
- containers.podman
- community.libvirt
- ansible.windows
- community.windows
+200
View File
@@ -0,0 +1,200 @@
---
# Install Prometheus + Windows Exporter on Windows and open firewall for Grafana
- name: Define Prometheus Versions and install dir
ansible.builtin.set_fact:
prometheus_version: "{{ prometheus_version | default('3.6.0') }}"
prometheus_install_dir: "{{ prometheus_install_dir | default('C:\\Prometheus') }}"
prometheus_listen_address: "{{ prometheus_listen_address | default('0.0.0.0:9090') }}"
nssm_dir: "{{ nssm_dir | default('C:\\nssm') }}"
nssm_version: "{{ nssm_version | default('2.24') }}"
windows_exporter_version: "{{ windows_exporter_version | default('0.31.3') }}"
windows_exporter_collectors: "{{ windows_exporter_collectors | default(['cache', 'cpu', 'cpu_info', 'diskdrive', 'memory', 'net', 'os', 'process', 'service', 'tcp', 'time', 'update']) }}"
- name: Define Windows Exporter defaults
ansible.builtin.set_fact:
__nssm_url: "https://nssm.cc/release/nssm-{{ nssm_version }}.zip"
__prometheus_zip_url: "https://github.com/prometheus/prometheus/releases/download/v{{ prometheus_version }}/prometheus-{{ prometheus_version }}.windows-amd64.zip"
__prometheus_zip_path: "{{ (ansible_env.TEMP | default('C:\\Windows\\Temp')) }}\\prometheus-{{ prometheus_version }}.zip"
__prometheus_home: "{{ prometheus_install_dir }}\\prometheus-{{ prometheus_version }}.windows-amd64"
__windows_exporter_msi_url: "https://github.com/prometheus-community/windows_exporter/releases/download/v{{ windows_exporter_version }}/windows_exporter-{{ windows_exporter_version }}-amd64.msi"
__windows_exporter_msi_path: "{{ (ansible_env.TEMP | default('C:\\Windows\\Temp')) }}\\windows_exporter-{{ windows_exporter_version }}-amd64.msi"
__nssm_zip_path: "{{ (ansible_env.TEMP | default('C:\\Windows\\Temp')) }}\\nssm.zip"
__nssm_exe: "{{ nssm_dir }}\\nssm.exe"
- name: Create Prometheus installation directories
ansible.windows.win_file:
path: "{{ item }}"
state: directory
loop:
- "{{ prometheus_install_dir }}"
- "{{ prometheus_install_dir }}\\data"
- "{{ nssm_dir }}"
- name: Download required files (Prometheus, NSSM, Windows Exporter)
ansible.windows.win_get_url:
url: "{{ item.url }}"
dest: "{{ item.dest }}"
force: false
loop:
- { url: "{{ __prometheus_zip_url }}", dest: "{{ __prometheus_zip_path }}" }
- { url: "{{ __nssm_url }}", dest: "{{ __nssm_zip_path }}" }
- {
url: "{{ __windows_exporter_msi_url }}",
dest: "{{ __windows_exporter_msi_path }}",
}
- name: Extract downloaded archives
community.windows.win_unzip:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
delete_archive: false
creates: "{{ item.creates | default(omit) }}"
loop:
- {
src: "{{ __prometheus_zip_path }}",
dest: "{{ prometheus_install_dir }}",
creates: "{{ __prometheus_home }}\\prometheus.exe",
}
- { src: "{{ __nssm_zip_path }}", dest: "{{ nssm_dir }}" }
- name: Verify Prometheus binary is present
ansible.windows.win_stat:
path: "{{ __prometheus_home }}\\prometheus.exe"
register: prometheus_bin
- name: Fail if Prometheus binary is missing
ansible.builtin.fail:
msg: >-
Prometheus binary not found at {{ __prometheus_home }}\prometheus.exe.
Check download/unzip and prometheus_version.
when: not prometheus_bin.stat.exists
- name: Deploy Prometheus configuration
ansible.windows.win_copy:
dest: "{{ prometheus_install_dir }}\\prometheus.yml"
content: |
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'windows'
static_configs:
- targets: ['localhost:9182']
- name: Check if promtool exists
ansible.windows.win_stat:
path: "{{ __prometheus_home }}\\promtool.exe"
register: promtool_bin
- name: Validate Prometheus config with promtool
ansible.windows.win_command: >-
"{{ __prometheus_home }}\promtool.exe"
check config
"{{ prometheus_install_dir }}\prometheus.yml"
register: promtool_check
changed_when: false
failed_when: promtool_check.rc != 0
when: promtool_bin.stat.exists
- name: Copy NSSM executable (win64)
ansible.windows.win_copy:
src: "{{ nssm_dir }}\\nssm-2.24\\win64\\nssm.exe"
dest: "{{ __nssm_exe }}"
remote_src: true
- name: Remove existing Prometheus service if present
ansible.windows.win_service:
name: Prometheus
state: absent
ignore_errors: true
- name: Install Prometheus service via NSSM
ansible.windows.win_command: >-
"{{ __nssm_exe }}"
install Prometheus
"{{ __prometheus_home }}\prometheus.exe"
--config.file={{ prometheus_install_dir }}\prometheus.yml
--storage.tsdb.path={{ prometheus_install_dir }}\data
--web.listen-address={{ prometheus_listen_address }}
--web.console.templates={{ __prometheus_home }}\consoles
--web.console.libraries={{ __prometheus_home }}\console_libraries
args:
chdir: "{{ __prometheus_home }}"
register: nssm_install
changed_when: nssm_install.rc == 0
- name: Set Prometheus AppDirectory via NSSM
ansible.windows.win_command: >-
"{{ __nssm_exe }}" set Prometheus AppDirectory "{{ __prometheus_home }}"
- name: Configure Prometheus stdout log via NSSM
ansible.windows.win_command: >-
"{{ __nssm_exe }}" set Prometheus AppStdout
"{{ prometheus_install_dir }}\prometheus-service.out.log"
- name: Configure Prometheus stderr log via NSSM
ansible.windows.win_command: >-
"{{ __nssm_exe }}" set Prometheus AppStderr
"{{ prometheus_install_dir }}\prometheus-service.err.log"
- name: Set Prometheus Start mode to AUTO via NSSM
ansible.windows.win_command: >-
"{{ __nssm_exe }}" set Prometheus Start SERVICE_AUTO_START
- name: Ensure Prometheus service is running (skip in check mode)
ansible.windows.win_service:
name: Prometheus
start_mode: auto
state: started
when: not ansible_check_mode | default(false)
- name: Wait for Prometheus to listen on 9090 (skip in check mode)
ansible.windows.win_wait_for:
port: 9090
delay: 0
timeout: 30
when: not ansible_check_mode | default(false)
- name: Install Windows Exporter
ansible.windows.win_package:
path: "{{ __windows_exporter_msi_path }}"
arguments: 'ENABLED_COLLECTORS={{ windows_exporter_collectors | join(",") }}'
state: present
- name: Ensure windows_exporter service is running
ansible.windows.win_service:
name: windows_exporter
start_mode: auto
state: started
- name: Set firewall remote IPs when string provided
ansible.builtin.set_fact:
grafana_remoteip: "{{ grafana_prometheus_sources }}"
when:
- grafana_prometheus_sources is defined
- grafana_prometheus_sources is string
- name: Set firewall remote IPs when list provided
ansible.builtin.set_fact:
grafana_remoteip: "{{ grafana_prometheus_sources | join(',') }}"
when:
- grafana_prometheus_sources is defined
- not (grafana_prometheus_sources is string)
- name: Allow inbound Prometheus (9090) from Grafana
community.windows.win_firewall_rule:
name: Prometheus 9090 (Grafana)
localport: 9090
protocol: tcp
direction: in
action: allow
enabled: true
# Provide one or more IPs/CIDRs in grafana_prometheus_sources (e.g. ['203.0.113.10'])
remoteip: "{{ grafana_remoteip | default(omit) }}"
state: present
+3
View File
@@ -105,3 +105,6 @@ game-01.lab.alexpires.me
[prometheus]
prod-01.alexpires.me
dev-01.lab.alexpires.me
[windows_prometheus]
game-01.lab.alexpires.me
@@ -1,164 +1,578 @@
{
"dashboard": {
"id": null,
"uid": "auth-exporter",
"title": "Auth Log Exporter",
"tags": [
"exporter",
"auth",
"prometheus"
],
"timezone": "browser",
"schemaVersion": 30,
"version": 1,
"refresh": "10s",
"templating": {
"list": [
{
"type": "datasource",
"name": "datasource",
"label": "Prometheus",
"query": "prometheus",
"current": {
"text": "Prometheus",
"value": "-- Grafana --"
}
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": {
"type": "grafana",
"uid": "-- Grafana --"
},
{
"type": "interval",
"name": "interval",
"label": "Interval",
"query": "5s,10s,30s,1m,5m",
"current": {
"text": "1m",
"value": "1m"
}
},
{
"type": "textbox",
"name": "topn",
"label": "Top N users",
"query": "10",
"current": {
"text": "10",
"value": "10"
}
}
]
},
"panels": [
{
"type": "timeseries",
"title": "Active sessions (by source)",
"id": 1,
"datasource": "${datasource}",
"targets": [
{
"expr": "auth_sessions_active",
"legendFormat": "{{source}}",
"refId": "A"
}
],
"gridPos": {
"x": 0,
"y": 0,
"w": 12,
"h": 8
}
},
{
"type": "timeseries",
"title": "Auth sessions started (rate)",
"id": 2,
"datasource": "${datasource}",
"targets": [
{
"expr": "sum by (source, method) (rate(auth_sessions_total[5m]))",
"legendFormat": "{{source}} / {{method}}",
"refId": "A"
}
],
"gridPos": {
"x": 12,
"y": 0,
"w": 12,
"h": 8
}
},
{
"type": "timeseries",
"title": "Parse errors (rate)",
"id": 3,
"datasource": "${datasource}",
"targets": [
{
"expr": "rate(auth_exporter_parse_errors_total[5m])",
"refId": "A"
}
],
"gridPos": {
"x": 0,
"y": 8,
"w": 12,
"h": 6
}
},
{
"type": "stat",
"title": "Exporter uptime (s)",
"id": 4,
"datasource": "${datasource}",
"targets": [
{
"expr": "auth_exporter_uptime_seconds",
"refId": "A"
}
],
"gridPos": {
"x": 12,
"y": 8,
"w": 6,
"h": 4
}
},
{
"type": "timeseries",
"title": "User label drops (rate)",
"id": 5,
"datasource": "${datasource}",
"targets": [
{
"expr": "rate(auth_exporter_user_labels_dropped_total[5m])",
"refId": "A"
}
],
"gridPos": {
"x": 18,
"y": 8,
"w": 6,
"h": 4
}
},
{
"type": "table",
"title": "Top users by session starts (last 5m)",
"id": 6,
"datasource": "${datasource}",
"targets": [
{
"expr": "topk(int(${topn}), sum by (username) (rate(auth_sessions_by_user_total[5m])))",
"legendFormat": "{{username}}",
"refId": "A"
}
],
"gridPos": {
"x": 0,
"y": 14,
"w": 24,
"h": 8
}
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"overwrite": false
"editable": true,
"fiscalYearStartMonth": 0,
"graphTooltip": 0,
"id": 0,
"links": [],
"panels": [
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 0
},
"id": 2,
"panels": [],
"title": "Sessions",
"type": "row"
},
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 0,
"y": 1
},
"id": 1,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "12.2.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"editorMode": "code",
"expr": "auth_sessions_active{}",
"legendFormat": "{{source}}",
"range": true,
"refId": "A"
}
],
"title": "Active sessions (by source)",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 7,
"w": 12,
"x": 12,
"y": 1
},
"id": 4,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "12.2.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"editorMode": "code",
"expr": "sum by (source, method) (rate(auth_sessions_total[5m]))",
"legendFormat": "{{source}} / {{method}}",
"range": true,
"refId": "A"
}
],
"title": "Auth sessions started (rate)",
"type": "timeseries"
},
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 8
},
"id": 6,
"panels": [],
"title": "Users",
"type": "row"
},
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 24,
"x": 0,
"y": 9
},
"id": 5,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "12.2.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"editorMode": "code",
"expr": "auth_sessions_by_user_total{}",
"legendFormat": "{{username}}:{{source}}",
"range": true,
"refId": "A"
}
],
"title": "Top users by session starts (last 5m)",
"type": "timeseries"
},
{
"collapsed": false,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 17
},
"id": 3,
"panels": [],
"title": "Exporter metrics",
"type": "row"
},
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 0,
"y": 18
},
"id": 7,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "12.2.0",
"targets": [
{
"datasource": {
"type": "prometheus",
"uid": "${datasource}"
},
"editorMode": "code",
"expr": "rate(auth_exporter_parse_errors_total[5m])",
"legendFormat": "{{instance}}",
"range": true,
"refId": "A"
}
],
"title": "Parse errors (rate)",
"type": "timeseries"
},
{
"datasource": {
"type": "prometheus",
"uid": "bezn5wieufi80d"
},
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisBorderShow": false,
"axisCenteredZero": false,
"axisColorMode": "text",
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"barWidthFactor": 0.6,
"drawStyle": "line",
"fillOpacity": 0,
"gradientMode": "none",
"hideFrom": {
"legend": false,
"tooltip": false,
"viz": false
},
"insertNulls": false,
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "auto",
"showValues": false,
"spanNulls": false,
"stacking": {
"group": "A",
"mode": "none"
},
"thresholdsStyle": {
"mode": "off"
}
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": 0
},
{
"color": "red",
"value": 80
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 8,
"w": 12,
"x": 12,
"y": 18
},
"id": 8,
"options": {
"legend": {
"calcs": [],
"displayMode": "list",
"placement": "bottom",
"showLegend": true
},
"tooltip": {
"hideZeros": false,
"mode": "single",
"sort": "none"
}
},
"pluginVersion": "12.2.0",
"targets": [
{
"editorMode": "code",
"expr": "rate(auth_exporter_user_labels_dropped_total[5m])",
"legendFormat": "{{instance}}",
"range": true,
"refId": "A"
}
],
"title": "User label drops (rate)",
"type": "timeseries"
}
],
"preload": false,
"schemaVersion": 42,
"tags": [],
"templating": {
"list": [
{
"current": {
"text": "prometheus-prod-01",
"value": "aezs0pa1i5xq8f"
},
"name": "datasource",
"options": [],
"query": "prometheus",
"refresh": 1,
"regex": "",
"type": "datasource"
}
]
},
"time": {
"from": "now-6h",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "Auth Exporter",
"uid": "7381c747-ecf6-4f2f-ac4b-551e56f24cf0",
"version": 4
}