Monitor your Elasticsearch cluster performance with Metricbeat for comprehensive metrics collection and visualization through pre-built Kibana dashboards. This tutorial covers installation, configuration, and automated alerting.
Prerequisites
- Elasticsearch 8.x cluster running
- Kibana 8.x installed
- Admin access to target systems
What this solves
Elasticsearch cluster monitoring is essential for maintaining performance, detecting issues, and ensuring high availability. Metricbeat provides lightweight, efficient monitoring by collecting metrics directly from Elasticsearch nodes and shipping them to your monitoring stack. This approach gives you real-time visibility into cluster health, node performance, index statistics, and query performance without impacting your production workloads.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you have the latest security patches and package information.
sudo apt update && sudo apt upgrade -y
Add Elastic repository
Add the official Elastic repository to install Metricbeat 8.15 with all security updates and official support.
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
sudo apt update
Install Metricbeat 8.15
Install Metricbeat from the official repository to ensure you get the latest features and security patches.
sudo apt install -y metricbeat
Configure Elasticsearch output
Configure Metricbeat to send metrics to your Elasticsearch cluster. Replace the connection details with your actual Elasticsearch endpoints.
sudo cp /etc/metricbeat/metricbeat.yml /etc/metricbeat/metricbeat.yml.backup
metricbeat.config.modules:
path: ${path.config}/modules.d/*.yml
reload.enabled: true
reload.period: 10s
output.elasticsearch:
hosts: ["localhost:9200"]
username: "elastic"
password: "your-elastic-password"
ssl:
enabled: true
verification_mode: certificate
certificate_authorities: ["/etc/elasticsearch/certs/http_ca.crt"]
setup.kibana:
host: "localhost:5601"
username: "elastic"
password: "your-elastic-password"
ssl:
enabled: true
verification_mode: certificate
certificate_authorities: ["/etc/elasticsearch/certs/http_ca.crt"]
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/metricbeat
name: metricbeat
keepfiles: 7
permissions: 0644
Enable Elasticsearch monitoring module
Enable the Elasticsearch module to collect comprehensive metrics including cluster health, node stats, and index performance.
sudo metricbeat modules enable elasticsearch
Configure Elasticsearch module settings
Configure the Elasticsearch module with your cluster connection details and specify which metrics to collect.
- module: elasticsearch
metricsets:
- node
- node_stats
- cluster_stats
- index
- index_recovery
- index_summary
- shard
- ml_job
period: 30s
hosts: ["https://localhost:9200"]
username: "elastic"
password: "your-elastic-password"
ssl:
enabled: true
verification_mode: certificate
certificate_authorities: ["/etc/elasticsearch/certs/http_ca.crt"]
xpack.enabled: true
scope: node
index_recovery.active_only: true
- module: elasticsearch
metricsets:
- ccr
- enrich
- ilm
period: 60s
hosts: ["https://localhost:9200"]
username: "elastic"
password: "your-elastic-password"
ssl:
enabled: true
verification_mode: certificate
certificate_authorities: ["/etc/elasticsearch/certs/http_ca.crt"]
xpack.enabled: true
Enable system monitoring module
Enable system monitoring to collect host metrics alongside Elasticsearch metrics for comprehensive monitoring.
sudo metricbeat modules enable system
- module: system
period: 30s
metricsets:
- cpu
- load
- memory
- network
- process
- process_summary
- socket_summary
- filesystem
- fsstat
processes: ['.*']
process.include_top_n:
by_cpu: 5
by_memory: 5
filesystem.ignore_types: []
- module: system
period: 1m
metricsets:
- diskio
- socket
diskio.include_devices: []
Test configuration
Test your Metricbeat configuration to ensure all settings are correct before starting the service.
sudo metricbeat test config
sudo metricbeat test output
Setup Kibana dashboards
Install the pre-built Kibana dashboards and index templates for Elasticsearch monitoring visualization.
sudo metricbeat setup --dashboards
sudo metricbeat setup --index-management
Set correct file permissions
Set appropriate file ownership and permissions for Metricbeat to run securely. The metricbeat user needs read access to configuration files.
sudo chown root:metricbeat /etc/metricbeat/metricbeat.yml
sudo chmod 640 /etc/metricbeat/metricbeat.yml
sudo chown -R root:metricbeat /etc/metricbeat/modules.d/
sudo chmod -R 640 /etc/metricbeat/modules.d/*.yml
Enable and start Metricbeat
Enable Metricbeat to start automatically on boot and start the service to begin collecting metrics.
sudo systemctl enable metricbeat
sudo systemctl start metricbeat
sudo systemctl status metricbeat
Configure Kibana dashboards and visualizations
Access Kibana web interface
Open your web browser and navigate to Kibana to access the monitoring dashboards. Use the elastic user credentials you configured.
https://localhost:5601
Import Elasticsearch monitoring dashboards
Navigate to Stack Management > Kibana > Saved Objects to verify the dashboards were imported correctly. Look for Elasticsearch monitoring dashboards.
Menu > Analytics > Dashboard
Search: "Elasticsearch"
Configure index patterns
Verify that Metricbeat index patterns are created and configured properly for data visualization.
Menu > Stack Management > Kibana > Index Patterns
Verify: "metricbeat-*" pattern exists
Access monitoring dashboards
Navigate to the Elasticsearch monitoring dashboards to view cluster metrics and performance data.
[Metricbeat Elasticsearch] Cluster Overview
[Metricbeat Elasticsearch] Node Overview
[Metricbeat Elasticsearch] Index Overview
Configure alerting and automated monitoring
Create Elasticsearch cluster health rule
Set up alerts for critical cluster health issues using Kibana's alerting framework.
Menu > Stack Management > Rules and Connectors > Rules
Click "Create rule"
Configure the rule with these settings:
Name: "Elasticsearch Cluster Health Alert"
Rule type: "Elasticsearch query"
Index: "metricbeat-*"
Query: "elasticsearch.cluster.status:red"
Threshold: "above 0"
Time window: "1m"
Configure email connector
Set up email notifications for alerts. You can integrate with Slack or Teams following similar patterns as in our Netdata alerts tutorial.
Connector type: Email
SMTP Host: your.smtp.server
Port: 587
Secure: true
User: alerts@example.com
Password: your-smtp-password
Create node performance alerts
Set up alerts for high CPU usage, memory pressure, and disk space issues on Elasticsearch nodes.
Name: "Elasticsearch Node High CPU"
Query: "elasticsearch.node.stats.process.cpu.percent:>90"
Threshold: "above 90"
Time window: "5m"
Actions: Send email notification
Name: "Elasticsearch Node Memory Pressure"
Query: "elasticsearch.node.stats.jvm.mem.heap_used_percent:>85"
Threshold: "above 85"
Time window: "3m"
Actions: Send email notification
Configure index monitoring alerts
Create alerts for index-specific issues like slow queries, indexing failures, and shard allocation problems.
Name: "Elasticsearch Slow Queries"
Query: "elasticsearch.node.stats.indices.search.query_time_in_millis:>5000"
Threshold: "above 5000"
Time window: "2m"
Actions: Send email notification
Verify your setup
Check that Metricbeat is running and collecting metrics from your Elasticsearch cluster.
sudo systemctl status metricbeat
sudo journalctl -u metricbeat -f --lines=20
Verify metrics are being indexed in Elasticsearch:
curl -k -u elastic:your-password 'https://localhost:9200/metricbeat-*/_search?q=metricset.module:elasticsearch&size=5&pretty'
Check Kibana dashboard data:
Navigate to: Dashboard > [Metricbeat Elasticsearch] Cluster Overview
Verify: Metrics are displaying with recent timestamps
Test alerting rules:
Menu > Stack Management > Rules and Connectors > Rules
Check: All rules show "OK" status
Test: Use "Run now" to test alert execution
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Metricbeat won't start | Configuration file syntax error | Run sudo metricbeat test config to validate syntax |
| Cannot connect to Elasticsearch | Wrong credentials or SSL configuration | Verify credentials and SSL certificate paths in config |
| No data in Kibana dashboards | Index pattern not created or wrong time range | Check index patterns and adjust time picker to show recent data |
| Permission denied errors | Incorrect file ownership or permissions | Run sudo chown -R root:metricbeat /etc/metricbeat and set correct permissions |
| Alerts not firing | Wrong query syntax or threshold values | Test queries in Kibana Discover and verify alert conditions |
| High memory usage | Too many metricsets enabled or short collection periods | Disable unnecessary metricsets and increase collection intervals |
Next steps
- Integrate Elasticsearch 8 with Prometheus monitoring and Grafana dashboards for additional monitoring perspectives
- Set up log alerting with Fluentd and Prometheus Alertmanager for comprehensive log monitoring
- Set up Kibana alerting and monitoring with Elasticsearch Watcher for advanced alerting scenarios
- Configure Elasticsearch index lifecycle management for automated data retention policies
- Configure Metricbeat for multi-node Elasticsearch cluster monitoring for large-scale deployments
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Elasticsearch Monitoring Setup with Metricbeat and Kibana
# Production-grade installation script
# Color codes
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Global variables
ELASTICSEARCH_HOST="${1:-localhost}"
ELASTICSEARCH_PORT="${2:-9200}"
KIBANA_HOST="${3:-localhost}"
KIBANA_PORT="${4:-5601}"
# Usage function
usage() {
echo "Usage: $0 [elasticsearch_host] [elasticsearch_port] [kibana_host] [kibana_port]"
echo "Example: $0 localhost 9200 localhost 5601"
exit 1
}
# Logging functions
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Cleanup function for rollback
cleanup() {
log_error "Installation failed. Performing cleanup..."
systemctl stop metricbeat 2>/dev/null || true
systemctl disable metricbeat 2>/dev/null || true
if [ "$PKG_MGR" = "apt" ]; then
apt remove -y metricbeat 2>/dev/null || true
else
$PKG_INSTALL remove -y metricbeat 2>/dev/null || true
fi
rm -f /etc/metricbeat/metricbeat.yml.bak
}
trap cleanup ERR
# Check if running as root or with sudo
check_privileges() {
if [ "$EUID" -ne 0 ]; then
log_error "This script must be run as root or with sudo"
exit 1
fi
}
# Detect OS and set package manager
detect_os() {
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update && apt upgrade -y"
REPO_SETUP="debian"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
REPO_SETUP="rhel"
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
REPO_SETUP="rhel"
;;
*)
log_error "Unsupported distribution: $ID"
exit 1
;;
esac
log_info "Detected OS: $PRETTY_NAME"
else
log_error "Cannot detect OS. /etc/os-release not found"
exit 1
fi
}
# Check prerequisites
check_prerequisites() {
echo "[1/8] Checking prerequisites..."
# Check if elasticsearch and kibana are accessible
if ! command -v curl >/dev/null 2>&1; then
log_warn "curl not found, installing..."
$PKG_INSTALL curl
fi
# Test Elasticsearch connectivity
if ! curl -s -f "http://${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}" >/dev/null 2>&1; then
log_warn "Cannot connect to Elasticsearch at ${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}"
log_warn "Please ensure Elasticsearch is running and accessible"
fi
log_info "Prerequisites check completed"
}
# Update system packages
update_system() {
echo "[2/8] Updating system packages..."
log_info "Running system update..."
$PKG_UPDATE
log_info "System update completed"
}
# Add Elastic repository
add_elastic_repo() {
echo "[3/8] Adding Elastic repository..."
if [ "$REPO_SETUP" = "debian" ]; then
# Install required packages
$PKG_INSTALL wget gpg apt-transport-https
# Add GPG key
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
# Add repository
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" > /etc/apt/sources.list.d/elastic-8.x.list
# Update package list
apt update
else
# RHEL-based systems
# Import GPG key
rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
# Create repository file
cat > /etc/yum.repos.d/elastic.repo << EOF
[elastic-8.x]
name=Elastic repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
EOF
fi
log_info "Elastic repository added successfully"
}
# Install Metricbeat
install_metricbeat() {
echo "[4/8] Installing Metricbeat..."
$PKG_INSTALL metricbeat
log_info "Metricbeat installed successfully"
}
# Configure Metricbeat
configure_metricbeat() {
echo "[5/8] Configuring Metricbeat..."
# Backup original config
cp /etc/metricbeat/metricbeat.yml /etc/metricbeat/metricbeat.yml.bak
# Create new configuration
cat > /etc/metricbeat/metricbeat.yml << EOF
# Metricbeat configuration for Elasticsearch monitoring
metricbeat.config.modules:
path: /etc/metricbeat/modules.d/*.yml
reload.enabled: true
reload.period: 30s
metricbeat.modules:
- module: elasticsearch
metricsets:
- node
- node_stats
- cluster_stats
- index
- index_summary
- index_recovery
- ccr
period: 30s
hosts: ["${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}"]
- module: system
metricsets:
- cpu
- memory
- network
- process
- process_summary
- filesystem
- diskio
enabled: true
period: 30s
processes: ['.*']
output.elasticsearch:
hosts: ["${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}"]
index: "metricbeat-%{+yyyy.MM.dd}"
setup.kibana:
host: "${KIBANA_HOST}:${KIBANA_PORT}"
setup.dashboards.enabled: true
setup.template.enabled: true
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
logging.level: info
logging.to_files: true
logging.files:
path: /var/log/metricbeat
name: metricbeat
keepfiles: 7
permissions: 0644
EOF
# Set proper ownership and permissions
chown root:root /etc/metricbeat/metricbeat.yml
chmod 644 /etc/metricbeat/metricbeat.yml
# Create log directory
mkdir -p /var/log/metricbeat
chown metricbeat:metricbeat /var/log/metricbeat
chmod 755 /var/log/metricbeat
log_info "Metricbeat configuration completed"
}
# Setup Kibana dashboards and templates
setup_kibana_assets() {
echo "[6/8] Setting up Kibana dashboards and index templates..."
# Setup Elasticsearch template and Kibana dashboards
metricbeat setup --dashboards --index-management
log_info "Kibana assets setup completed"
}
# Start and enable services
start_services() {
echo "[7/8] Starting and enabling Metricbeat service..."
# Enable and start metricbeat
systemctl enable metricbeat
systemctl start metricbeat
# Wait a moment for the service to start
sleep 3
# Check service status
if systemctl is-active --quiet metricbeat; then
log_info "Metricbeat service started successfully"
else
log_error "Failed to start Metricbeat service"
journalctl -u metricbeat --no-pager -l
exit 1
fi
}
# Verify installation
verify_installation() {
echo "[8/8] Verifying installation..."
# Check service status
if systemctl is-active --quiet metricbeat; then
log_info "✓ Metricbeat service is running"
else
log_error "✗ Metricbeat service is not running"
return 1
fi
# Wait for data to be indexed
log_info "Waiting 30 seconds for metrics to be collected..."
sleep 30
# Check if data is being indexed
local data_check
data_check=$(curl -s -f "http://${ELASTICSEARCH_HOST}:${ELASTICSEARCH_PORT}/metricbeat-*/_search?q=metricset.module:elasticsearch&size=1" 2>/dev/null || echo "")
if echo "$data_check" | grep -q "elasticsearch"; then
log_info "✓ Elasticsearch metrics are being collected"
else
log_warn "! No Elasticsearch metrics found yet. This may be normal for a new installation."
fi
# Show recent logs
log_info "Recent Metricbeat logs:"
journalctl -u metricbeat --no-pager -l -n 5
log_info "Installation completed successfully!"
echo ""
log_info "Next steps:"
echo "1. Access Kibana at http://${KIBANA_HOST}:${KIBANA_PORT}"
echo "2. Go to Dashboard and search for 'Elasticsearch' to view monitoring dashboards"
echo "3. Check Stack Management > Index Patterns for 'metricbeat-*' pattern"
echo "4. Configure alerts in Stack Management > Rules and Connectors"
echo ""
log_info "Useful commands:"
echo "- Check status: sudo systemctl status metricbeat"
echo "- View logs: sudo journalctl -u metricbeat -f"
echo "- Test config: sudo metricbeat test config"
}
# Main execution
main() {
log_info "Starting Elasticsearch Monitoring Setup with Metricbeat"
check_privileges
detect_os
check_prerequisites
update_system
add_elastic_repo
install_metricbeat
configure_metricbeat
setup_kibana_assets
start_services
verify_installation
log_info "Elasticsearch monitoring setup completed successfully!"
}
# Run main function
main "$@"
Review the script before running. Execute with: bash install.sh