#!/bin/bash # Promtail Installation and Configuration Script for Debian # Usage: bash -c "$(curl -fsSL /install-promtail.sh)" set -e # Configuration LOKI_ENDPOINT="loki.pfotenballen.de" LOKI_PORT="3100" PROMTAIL_VERSION="2.9.2" PROMTAIL_USER="promtail" PROMTAIL_DIR="/opt/promtail" CONFIG_DIR="/etc/promtail" LOG_DIR="/var/log/promtail" # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Logging functions log_info() { echo -e "${BLUE}[INFO]${NC} $1" } log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } # Check if running as root check_root() { if [[ $EUID -ne 0 ]]; then log_error "This script must be run as root" exit 1 fi } # Check if promtail is already installed check_promtail_installed() { if command -v promtail &> /dev/null || [[ -f "/usr/local/bin/promtail" ]] || [[ -f "$PROMTAIL_DIR/promtail" ]]; then return 0 else return 1 fi } # Test Loki endpoint connectivity test_loki_connectivity() { log_info "Testing connectivity to Loki endpoint: $LOKI_ENDPOINT:$LOKI_PORT" if timeout 10 bash -c "/dev/null; then log_success "Successfully connected to $LOKI_ENDPOINT:$LOKI_PORT" return 0 else log_error "Cannot reach $LOKI_ENDPOINT:$LOKI_PORT" log_error "Please check your network connection and Loki server status" return 1 fi } # Install dependencies install_dependencies() { log_info "Installing dependencies..." apt-get update -qq apt-get install -y wget curl unzip systemd log_success "Dependencies installed" } # Create promtail user create_promtail_user() { if ! id "$PROMTAIL_USER" &>/dev/null; then log_info "Creating promtail user..." useradd --system --no-create-home --shell /bin/false $PROMTAIL_USER log_success "Promtail user created" else log_info "Promtail user already exists" fi } # Download and install promtail install_promtail() { log_info "Downloading Promtail v$PROMTAIL_VERSION..." # Determine architecture ARCH=$(uname -m) case $ARCH in x86_64) ARCH_SUFFIX="amd64" ;; aarch64) ARCH_SUFFIX="arm64" ;; armv7l) ARCH_SUFFIX="armv7" ;; *) log_error "Unsupported architecture: $ARCH" exit 1 ;; esac # Create directories mkdir -p $PROMTAIL_DIR mkdir -p $CONFIG_DIR mkdir -p $LOG_DIR # Download promtail binary DOWNLOAD_URL="https://github.com/grafana/loki/releases/download/v$PROMTAIL_VERSION/promtail-linux-$ARCH_SUFFIX.zip" cd /tmp wget -q "$DOWNLOAD_URL" -O promtail.zip unzip -q promtail.zip # Install binary chmod +x promtail-linux-$ARCH_SUFFIX mv promtail-linux-$ARCH_SUFFIX /usr/local/bin/promtail # Set ownership chown root:root /usr/local/bin/promtail chown -R $PROMTAIL_USER:$PROMTAIL_USER $CONFIG_DIR $LOG_DIR # Cleanup rm -f promtail.zip log_success "Promtail installed successfully" } # Create promtail configuration create_config() { log_info "Creating Promtail configuration..." # Get the actual hostname HOSTNAME=$(hostname) cat > $CONFIG_DIR/promtail.yml << EOF server: http_listen_port: 9080 grpc_listen_port: 0 positions: filename: /var/lib/promtail/positions.yaml clients: - url: http://$LOKI_ENDPOINT:$LOKI_PORT/loki/api/v1/push scrape_configs: # Direct /var/log/ files (system logs) - job_name: system-logs static_configs: - targets: - localhost labels: job: system-logs service: system host: $HOSTNAME __path__: /var/log/*.log # Service-specific logs in subdirectories - job_name: service-logs static_configs: - targets: - localhost labels: job: service-logs host: $HOSTNAME __path__: /var/log/*/*.log pipeline_stages: - regex: expression: '/var/log/(?P[^/]+)/.*' - labels: service: '{{ .service }}' # Recursively capture all nested logs (deeper than one level) - job_name: nested-service-logs static_configs: - targets: - localhost labels: job: nested-service-logs host: $HOSTNAME __path__: /var/log/**/*.log pipeline_stages: - regex: expression: '/var/log/(?P[^/]+)/.*' - labels: service: '{{ .service }}' EOF # Create positions directory mkdir -p /var/lib/promtail chown $PROMTAIL_USER:$PROMTAIL_USER /var/lib/promtail # Set proper permissions chown $PROMTAIL_USER:$PROMTAIL_USER $CONFIG_DIR/promtail.yml chmod 640 $CONFIG_DIR/promtail.yml log_success "Configuration created" } # Create systemd service create_systemd_service() { log_info "Creating systemd service..." cat > /etc/systemd/system/promtail.service << EOF [Unit] Description=Promtail service Documentation=https://grafana.com/docs/loki/latest/clients/promtail/ After=network.target [Service] Type=simple User=$PROMTAIL_USER ExecStart=/usr/local/bin/promtail -config.file=$CONFIG_DIR/promtail.yml Restart=always RestartSec=10 StandardOutput=journal StandardError=journal SyslogIdentifier=promtail [Install] WantedBy=multi-user.target EOF systemctl daemon-reload log_success "Systemd service created" } # Add promtail user to adm group for log access configure_log_access() { log_info "Configuring log file access..." usermod -a -G adm $PROMTAIL_USER log_success "Log access configured" } # Start and enable service start_service() { log_info "Starting Promtail service..." systemctl enable promtail systemctl start promtail # Wait a moment and check status sleep 2 if systemctl is-active --quiet promtail; then log_success "Promtail service is running" log_info "Service status:" systemctl status promtail --no-pager -l else log_error "Failed to start Promtail service" log_error "Check logs with: journalctl -u promtail -f" exit 1 fi } # Main installation process main() { echo "==================================" echo " Promtail Installation Script " echo "==================================" echo check_root if check_promtail_installed; then log_warning "Promtail appears to be already installed" echo "Existing installation found. Do you want to continue and reconfigure? (y/N)" read -r response if [[ ! "$response" =~ ^[Yy]$ ]]; then log_info "Installation cancelled" exit 0 fi fi # Test Loki connectivity first if ! test_loki_connectivity; then echo "Do you want to continue anyway? (y/N)" read -r response if [[ ! "$response" =~ ^[Yy]$ ]]; then log_info "Installation cancelled" exit 1 fi fi install_dependencies create_promtail_user if ! check_promtail_installed; then install_promtail else log_info "Promtail binary already exists, skipping download" fi create_config create_systemd_service configure_log_access start_service echo echo "==================================" log_success "Promtail installation completed!" echo "==================================" echo echo "Configuration file: $CONFIG_DIR/promtail.yml" echo "Service status: systemctl status promtail" echo "Service logs: journalctl -u promtail -f" echo "Loki endpoint: http://$LOKI_ENDPOINT:$LOKI_PORT" echo echo "To check if logs are being sent to Loki:" echo "curl -G -s \"http://$LOKI_ENDPOINT:$LOKI_PORT/loki/api/v1/query\" --data-urlencode 'query={job=\"system-logs\"}'" } # Execute main function main "$@"