Short answer
- Collect CPU, memory, disk, I/O and connection metrics with Prometheus and node_exporter, and view them in Grafana.
- Ship authentication, web server, application and auditd logs to a separate machine with Grafana Alloy and Loki, so an intruder cannot erase them.
- Alert on symptoms your users feel, such as error rate and latency, rather than on every CPU spike.
- Keep logs long enough to investigate an incident and to meet the NIS2 and GDPR notification deadlines.
- System metrics
- Prometheus + node_exporter, dashboards in Grafana
- Logs
- Grafana Alloy to Loki, on a separate machine
- Logs you need
- auth, nginx access and error, application, auditd
- Alerting principle
- on SLOs and symptoms, not on every metric
What to measure and what to read
Metrics tell you something is wrong; logs tell you what. Four metrics are mandatory on any server: free disk space, available memory, CPU load and open connections. For a web application add the 5xx error rate and 95th-percentile latency. Among the logs, authentication shows brute force and unusual logins, nginx shows scans and exploitation attempts, the application shows exceptions, and auditd records commands run as root and changes to sensitive files. You read them locally with journalctl; the central system keeps them.
Why logs leave the server, and why you alert on little
The first thing an intruder does is clean the logs. If the only copy sits on the compromised machine, the investigation ends before it begins, so Grafana Alloy forwards logs in real time to a machine where production holds only an ingestion channel. Alerts work the opposite way: the more of them there are, the more they get ignored. Define a service level objective, such as at least 999 of every 1,000 requests succeeding, and alert when you burn through it too fast. Disk under 10 % free, or a login from outside the VPN, is worth waking someone for.
- Retention: 30–90 days for metrics, at least 6 months for security logs
- NTP on every machine, or correlating events is impossible
- An alert with no runbook, meaning no 'what do I do when this fires', ends up muted
What Romanian law expects
OUG 155/2024, the NIS2 transposition approved by Law 124/2025, requires entities registered with DNSC to send an early warning within 24 hours of identifying a significant incident, a notification within 72 hours and a final report one month later. Without logs and metrics you can neither identify the incident nor write the report. GDPR Article 33 requires notifying ANSPDCP within 72 hours of learning about a breach, and Article 32 requires the ability to detect one. Logs contain IP addresses, which are personal data, so give them a defined retention period and limited access.
What to monitor on a production server and when to alert| Signal | Source | Typical alert threshold | Why it matters |
|---|
| Disk space | node_exporter | under 10–15 % free for 15 minutes | The database refuses writes and logs are lost |
|---|
| HTTP 5xx errors | nginx, application | over 1 % of requests for 5 minutes | A direct symptom for users |
|---|
| p95 latency | application, nginx | above your defined SLO | Degradation before an outage |
|---|
| SSH logins | auth.log / journal | a successful login from outside the VPN | Brute force, compromised account |
|---|
| Sensitive files | auditd | any change in /etc/ssh or /etc/sudoers.d | Attacker persistence |
|---|
| TLS certificate | blackbox_exporter | expires in under 14 days | The site becomes unreachable on expiry |
|---|
Commands and configuration
Quickly read what happened in the last hourjournalctl --since "-1h" -p warning
journalctl -u ssh --since today | grep -E "Accepted|Failed"
sudo ausearch -m EXECVE -ts recent
Grafana Alloy: ship logs to the log machine// /etc/alloy/config.alloy
loki.write "central" {
endpoint { url = "http://10.0.0.20:3100/loki/api/v1/push" }
}
local.file_match "system" {
path_targets = [
{__path__ = "/var/log/auth.log", job = "varlogs", host = "web-01"},
{__path__ = "/var/log/nginx/*.log", job = "varlogs", host = "web-01"},
]
}
loki.source.file "system" {
targets = local.file_match.system.targets
forward_to = [loki.write.central.receiver]
}
Prometheus: disk alert with a delay to avoid noisegroups:
- name: server
rules:
- alert: DiskAlmostFull
expr: node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} < 0.10
for: 15m
labels:
severity: critical
annotations:
summary: "Under 10 % free space on / ({{ $labels.instance }})"
Practical examples
Online retailer in Bucharest on a single VPS
A night of aggressive scanning filled the disk with nginx logs and PostgreSQL began refusing writes. Nobody knew until the first complaint at breakfast. An alert at 15 % free space and a correct logrotate setup removed that whole class of incident.
Web agency in Timisoara running ten customer servers
On one compromised server the authentication logs had been wiped, so nobody knew how long the intruder had been inside. The copy in Loki, on a separate machine, showed the first successful login three weeks earlier, using an SSH key added by a former contractor.
Common mistakes
- Keeping logs only on the monitored server, exactly where an attacker has control.
- Alerting on CPU above 80 % and, a week later, the whole team ignoring the alert channel.
- Monitoring the server but not the application: the server is 'green' while every request returns a 500.
- Running the monitoring system on the same server it is supposed to watch.
How 4hosting helps
- CI/CD & Monitoring installs Grafana, Prometheus and Loki, defines SLO-based alerting and writes the runbooks. Your plan includes the hours: 1 h a month from cPanel Advanced up, 1–8 h on VPS, 5–10 h on dedicated servers (depending on plan), 10 h on GPU servers.
- Request those hours from the client panel; they are not carried over, and extra hours are accepted and billed separately.
- SIEM & Incident Response centralises security logs, correlates them and alerts on attack patterns; after an incident it produces the post-incident report.
- With a data centre in Frankfurt, you can keep the log machine in an EU location separate from production.
Related questions
How long should I keep logs?
Keep security logs, meaning authentication, sudo and auditd, for at least six months so you can investigate an incident found late. Web access logs contain IP addresses, which are personal data, so keep them for a period set in your GDPR policy, often 30–90 days, then aggregate or delete them.
Do I need Prometheus and Grafana for a single VPS?
For one server, an external uptime check plus simple disk and memory alerts can be enough at first. Prometheus and Loki become necessary once you run several machines or when you have to prove what happened during an incident.
What is the difference between monitoring and a SIEM?
Monitoring tracks system health: resources, errors, latency. A SIEM collects security events from several sources and correlates them, for example 500 failed logins followed by a successful one, then a new key in authorized_keys. On a small server, Loki with a few rules can cover both roles.