Ultima attività 1750263007

Revisione ef48cd980f0e6f86eeff9c2ec9a51955e3fc17c3

install-promtail.sh Raw
1#!/bin/bash
2
3# Universal Promtail Installation and Configuration Script
4# Supports: Debian, Ubuntu, CentOS, RHEL, Fedora, Arch Linux, Alpine, Raspberry Pi OS
5# Usage: bash -c "$(curl -fsSL <your-gist-url>/install-promtail.sh)"
6
7set -e
8
9# Configuration
10LOKI_ENDPOINT="loki.pfotenballen.de"
11LOKI_PORT="3100"
12PROMTAIL_VERSION="2.9.2"
13PROMTAIL_USER="promtail"
14PROMTAIL_DIR="/opt/promtail"
15CONFIG_DIR="/etc/promtail"
16LOG_DIR="/var/log/promtail"
17
18# OS Detection Variables
19OS=""
20DIST=""
21PACKAGE_MANAGER=""
22SERVICE_MANAGER=""
23
24# Colors for output
25RED='\033[0;31m'
26GREEN='\033[0;32m'
27YELLOW='\033[1;33m'
28BLUE='\033[0;34m'
29NC='\033[0m' # No Color
30
31# Logging functions
32log_info() {
33 echo -e "${BLUE}[INFO]${NC} $1"
34}
35
36log_success() {
37 echo -e "${GREEN}[SUCCESS]${NC} $1"
38}
39
40log_warning() {
41 echo -e "${YELLOW}[WARNING]${NC} $1"
42}
43
44log_error() {
45 echo -e "${RED}[ERROR]${NC} $1"
46}
47
48# Detect OS and Distribution
49detect_os() {
50 log_info "Detecting operating system..."
51
52 if [[ -f /etc/os-release ]]; then
53 . /etc/os-release
54 OS=$ID
55 DIST=$VERSION_ID
56 elif command -v lsb_release >/dev/null 2>&1; then
57 OS=$(lsb_release -si | tr '[:upper:]' '[:lower:]')
58 DIST=$(lsb_release -sr)
59 elif [[ -f /etc/redhat-release ]]; then
60 OS="rhel"
61 DIST=$(cat /etc/redhat-release | sed 's/.*release \([0-9]\).*/\1/')
62 else
63 log_error "Cannot detect operating system"
64 exit 1
65 fi
66
67 # Determine package manager
68 if command -v apt-get >/dev/null 2>&1; then
69 PACKAGE_MANAGER="apt"
70 elif command -v yum >/dev/null 2>&1; then
71 PACKAGE_MANAGER="yum"
72 elif command -v dnf >/dev/null 2>&1; then
73 PACKAGE_MANAGER="dnf"
74 elif command -v pacman >/dev/null 2>&1; then
75 PACKAGE_MANAGER="pacman"
76 elif command -v apk >/dev/null 2>&1; then
77 PACKAGE_MANAGER="apk"
78 else
79 log_error "No supported package manager found"
80 exit 1
81 fi
82
83 # Determine service manager
84 if command -v systemctl >/dev/null 2>&1 && systemctl --version >/dev/null 2>&1; then
85 SERVICE_MANAGER="systemd"
86 elif command -v service >/dev/null 2>&1; then
87 SERVICE_MANAGER="sysv"
88 elif command -v rc-service >/dev/null 2>&1; then
89 SERVICE_MANAGER="openrc"
90 else
91 log_error "No supported service manager found"
92 exit 1
93 fi
94
95 log_info "Detected: OS=$OS, Package Manager=$PACKAGE_MANAGER, Service Manager=$SERVICE_MANAGER"
96}
97
98# Check if running as root
99check_root() {
100 if [[ $EUID -ne 0 ]]; then
101 log_error "This script must be run as root"
102 exit 1
103 fi
104}
105
106# Check if promtail is already installed
107check_promtail_installed() {
108 if command -v promtail &> /dev/null || [[ -f "/usr/local/bin/promtail" ]] || [[ -f "$PROMTAIL_DIR/promtail" ]]; then
109 return 0
110 else
111 return 1
112 fi
113}
114
115# Test Loki endpoint connectivity
116test_loki_connectivity() {
117 log_info "Testing connectivity to Loki endpoint: $LOKI_ENDPOINT:$LOKI_PORT"
118
119 if command -v nc >/dev/null 2>&1; then
120 # Use netcat if available
121 if timeout 10 nc -z "$LOKI_ENDPOINT" "$LOKI_PORT" 2>/dev/null; then
122 log_success "Successfully connected to $LOKI_ENDPOINT:$LOKI_PORT"
123 return 0
124 fi
125 elif command -v telnet >/dev/null 2>&1; then
126 # Use telnet as fallback
127 if timeout 10 bash -c "echo 'quit' | telnet $LOKI_ENDPOINT $LOKI_PORT" 2>/dev/null | grep -q "Connected"; then
128 log_success "Successfully connected to $LOKI_ENDPOINT:$LOKI_PORT"
129 return 0
130 fi
131 elif command -v curl >/dev/null 2>&1; then
132 # Use curl as last resort
133 if timeout 10 curl -s "http://$LOKI_ENDPOINT:$LOKI_PORT/ready" >/dev/null 2>&1; then
134 log_success "Successfully connected to $LOKI_ENDPOINT:$LOKI_PORT"
135 return 0
136 fi
137 fi
138
139 log_error "Cannot reach $LOKI_ENDPOINT:$LOKI_PORT"
140 log_error "Please check your network connection and Loki server status"
141 return 1
142}
143
144# Install dependencies
145install_dependencies() {
146 log_info "Installing dependencies..."
147
148 case $PACKAGE_MANAGER in
149 "apt")
150 export DEBIAN_FRONTEND=noninteractive
151 apt-get update -qq
152 apt-get install -y wget curl unzip netcat-openbsd || apt-get install -y wget curl unzip netcat
153 ;;
154 "yum")
155 yum install -y wget curl unzip nc
156 ;;
157 "dnf")
158 dnf install -y wget curl unzip nc
159 ;;
160 "pacman")
161 pacman -Sy --noconfirm wget curl unzip netcat
162 ;;
163 "apk")
164 apk update
165 apk add wget curl unzip netcat-openbsd
166 ;;
167 *)
168 log_error "Unsupported package manager: $PACKAGE_MANAGER"
169 exit 1
170 ;;
171 esac
172
173 log_success "Dependencies installed"
174}
175
176# Create promtail user
177create_promtail_user() {
178 if ! id "$PROMTAIL_USER" &>/dev/null; then
179 log_info "Creating promtail user..."
180
181 case $OS in
182 "alpine")
183 adduser -S -D -H -s /bin/false $PROMTAIL_USER
184 ;;
185 *)
186 if command -v useradd >/dev/null 2>&1; then
187 useradd --system --no-create-home --shell /bin/false $PROMTAIL_USER 2>/dev/null || \
188 useradd -r -M -s /bin/false $PROMTAIL_USER
189 else
190 log_error "Cannot create user - useradd not available"
191 exit 1
192 fi
193 ;;
194 esac
195
196 log_success "Promtail user created"
197 else
198 log_info "Promtail user already exists"
199 fi
200}
201
202# Download and install promtail
203install_promtail() {
204 log_info "Downloading Promtail v$PROMTAIL_VERSION..."
205
206 # Determine architecture
207 ARCH=$(uname -m)
208 case $ARCH in
209 x86_64)
210 ARCH_SUFFIX="amd64"
211 ;;
212 aarch64)
213 ARCH_SUFFIX="arm64"
214 ;;
215 armv7l)
216 ARCH_SUFFIX="arm"
217 ;;
218 arm*)
219 ARCH_SUFFIX="arm"
220 ;;
221 *)
222 log_error "Unsupported architecture: $ARCH"
223 exit 1
224 ;;
225 esac
226
227 # Create directories
228 mkdir -p $PROMTAIL_DIR
229 mkdir -p $CONFIG_DIR
230 mkdir -p $LOG_DIR
231
232 # Download promtail binary
233 DOWNLOAD_URL="https://github.com/grafana/loki/releases/download/v$PROMTAIL_VERSION/promtail-linux-$ARCH_SUFFIX.zip"
234
235 cd /tmp
236 log_info "Downloading from: $DOWNLOAD_URL"
237 if ! wget --timeout=30 --tries=3 -q "$DOWNLOAD_URL" -O promtail.zip; then
238 log_error "Failed to download Promtail. Check internet connection."
239 exit 1
240 fi
241
242 if ! unzip -q promtail.zip; then
243 log_error "Failed to extract Promtail archive"
244 exit 1
245 fi
246
247 # Install binary
248 chmod +x promtail-linux-$ARCH_SUFFIX
249 mv promtail-linux-$ARCH_SUFFIX /usr/local/bin/promtail
250
251 # Set ownership
252 chown root:root /usr/local/bin/promtail
253 chown -R $PROMTAIL_USER:$PROMTAIL_USER $CONFIG_DIR $LOG_DIR
254
255 # Cleanup
256 rm -f promtail.zip
257
258 log_success "Promtail installed successfully"
259}
260
261# Create promtail configuration
262create_config() {
263 log_info "Creating Promtail configuration..."
264
265 # Get the actual hostname
266 HOSTNAME=$(hostname)
267
268 cat > $CONFIG_DIR/promtail.yml << EOF
269server:
270 http_listen_port: 9080
271 grpc_listen_port: 0
272
273positions:
274 filename: /var/lib/promtail/positions.yaml
275
276clients:
277 - url: http://$LOKI_ENDPOINT:$LOKI_PORT/loki/api/v1/push
278
279scrape_configs:
280 # Direct /var/log/ files (system logs)
281 - job_name: system-logs
282 static_configs:
283 - targets:
284 - localhost
285 labels:
286 job: system-logs
287 service: system
288 host: $HOSTNAME
289 __path__: /var/log/*.log
290
291 # Service-specific logs in subdirectories
292 - job_name: service-logs
293 static_configs:
294 - targets:
295 - localhost
296 labels:
297 job: service-logs
298 host: $HOSTNAME
299 __path__: /var/log/*/*.log
300 pipeline_stages:
301 - regex:
302 expression: '/var/log/(?P<service>[^/]+)/.*'
303 - labels:
304 service: '{{ .service }}'
305
306 # Recursively capture all nested logs (deeper than one level)
307 - job_name: nested-service-logs
308 static_configs:
309 - targets:
310 - localhost
311 labels:
312 job: nested-service-logs
313 host: $HOSTNAME
314 __path__: /var/log/**/*.log
315 pipeline_stages:
316 - regex:
317 expression: '/var/log/(?P<service>[^/]+)/.*'
318 - labels:
319 service: '{{ .service }}'
320EOF
321
322 # Create positions directory
323 mkdir -p /var/lib/promtail
324 chown $PROMTAIL_USER:$PROMTAIL_USER /var/lib/promtail
325
326 # Set proper permissions
327 chown $PROMTAIL_USER:$PROMTAIL_USER $CONFIG_DIR/promtail.yml
328 chmod 640 $CONFIG_DIR/promtail.yml
329
330 log_success "Configuration created"
331}
332
333# Create service
334create_service() {
335 case $SERVICE_MANAGER in
336 "systemd")
337 create_systemd_service
338 ;;
339 "sysv")
340 create_sysv_service
341 ;;
342 "openrc")
343 create_openrc_service
344 ;;
345 *)
346 log_error "Unsupported service manager: $SERVICE_MANAGER"
347 exit 1
348 ;;
349 esac
350}
351
352# Create systemd service
353create_systemd_service() {
354 log_info "Creating systemd service..."
355
356 cat > /etc/systemd/system/promtail.service << EOF
357[Unit]
358Description=Promtail service
359Documentation=https://grafana.com/docs/loki/latest/clients/promtail/
360After=network.target
361
362[Service]
363Type=simple
364User=$PROMTAIL_USER
365ExecStart=/usr/local/bin/promtail -config.file=$CONFIG_DIR/promtail.yml
366Restart=always
367RestartSec=10
368StandardOutput=journal
369StandardError=journal
370SyslogIdentifier=promtail
371
372[Install]
373WantedBy=multi-user.target
374EOF
375
376 systemctl daemon-reload
377 log_success "Systemd service created"
378}
379
380# Create SysV init script
381create_sysv_service() {
382 log_info "Creating SysV init script..."
383
384 cat > /etc/init.d/promtail << 'EOF'
385#!/bin/bash
386# promtail Promtail log collector
387# chkconfig: 35 80 20
388# description: Promtail log collector for Grafana Loki
389
390. /etc/rc.d/init.d/functions
391
392USER="promtail"
393DAEMON="promtail"
394ROOT_DIR="/var/lib/promtail"
395
396SERVER="$ROOT_DIR/$DAEMON"
397LOCK_FILE="/var/lock/subsys/promtail"
398
399start() {
400 if [ -f $LOCK_FILE ]; then
401 echo "promtail is locked."
402 return 1
403 fi
404
405 echo -n $"Shutting down $DAEMON: "
406 pid=`ps -aefw | grep "$DAEMON" | grep -v " grep " | awk '{print $2}'`
407 kill -9 $pid > /dev/null 2>&1
408 [ $? -eq 0 ] && echo "OK" || echo "FAILED"
409}
410
411stop() {
412 echo -n $"Shutting down $DAEMON: "
413 pid=`ps -aefw | grep "$DAEMON" | grep -v " grep " | awk '{print $2}'`
414 kill -9 $pid > /dev/null 2>&1
415 [ $? -eq 0 ] && echo "OK" || echo "FAILED"
416 rm -f $LOCK_FILE
417}
418
419case "$1" in
420 start)
421 start
422 ;;
423 stop)
424 stop
425 ;;
426 status)
427 status $DAEMON
428 ;;
429 restart)
430 stop
431 start
432 ;;
433 *)
434 echo "Usage: {start|stop|status|restart}"
435 exit 1
436 ;;
437esac
438
439exit $?
440EOF
441
442 chmod +x /etc/init.d/promtail
443 chkconfig --add promtail 2>/dev/null || update-rc.d promtail defaults
444 log_success "SysV service created"
445}
446
447# Create OpenRC service
448create_openrc_service() {
449 log_info "Creating OpenRC service..."
450
451 cat > /etc/init.d/promtail << EOF
452#!/sbin/openrc-run
453
454name="promtail"
455description="Promtail log collector"
456
457command="/usr/local/bin/promtail"
458command_args="-config.file=$CONFIG_DIR/promtail.yml"
459command_user="$PROMTAIL_USER"
460command_background="yes"
461pidfile="/run/\${RC_SVCNAME}.pid"
462
463depend() {
464 need net
465 after firewall
466}
467EOF
468
469 chmod +x /etc/init.d/promtail
470 log_success "OpenRC service created"
471}
472
473# Add promtail user to log access groups
474configure_log_access() {
475 log_info "Configuring log file access..."
476
477 # Try to add to common log access groups
478 for group in adm systemd-journal wheel; do
479 if getent group $group >/dev/null 2>&1; then
480 usermod -a -G $group $PROMTAIL_USER 2>/dev/null || true
481 log_info "Added to group: $group"
482 fi
483 done
484
485 log_success "Log access configured"
486}
487
488# Start and enable service
489start_service() {
490 log_info "Starting Promtail service..."
491
492 case $SERVICE_MANAGER in
493 "systemd")
494 systemctl enable promtail
495 systemctl start promtail
496 sleep 2
497 if systemctl is-active --quiet promtail; then
498 log_success "Promtail service is running"
499 systemctl status promtail --no-pager -l
500 else
501 log_error "Failed to start Promtail service"
502 log_error "Check logs with: journalctl -u promtail -f"
503 exit 1
504 fi
505 ;;
506 "sysv")
507 service promtail start
508 chkconfig promtail on 2>/dev/null || update-rc.d promtail enable
509 if service promtail status >/dev/null 2>&1; then
510 log_success "Promtail service is running"
511 else
512 log_error "Failed to start Promtail service"
513 exit 1
514 fi
515 ;;
516 "openrc")
517 rc-update add promtail default
518 rc-service promtail start
519 if rc-service promtail status >/dev/null 2>&1; then
520 log_success "Promtail service is running"
521 else
522 log_error "Failed to start Promtail service"
523 exit 1
524 fi
525 ;;
526 esac
527}
528
529# Main installation process
530main() {
531 echo "=================================="
532 echo " Promtail Installation Script "
533 echo "=================================="
534 echo
535
536 check_root
537 detect_os
538
539 if check_promtail_installed; then
540 log_warning "Promtail appears to be already installed"
541 if [[ -t 0 ]]; then
542 echo "Existing installation found. Do you want to continue and reconfigure? (y/N)"
543 read -r response
544 if [[ ! "$response" =~ ^[Yy]$ ]]; then
545 log_info "Installation cancelled"
546 exit 0
547 fi
548 else
549 log_info "Non-interactive mode: Reconfiguring existing installation"
550 fi
551 fi
552
553 # Test Loki connectivity first
554 if ! test_loki_connectivity; then
555 if [[ -t 0 ]]; then
556 echo "Do you want to continue anyway? (y/N)"
557 read -r response
558 if [[ ! "$response" =~ ^[Yy]$ ]]; then
559 log_info "Installation cancelled"
560 exit 1
561 fi
562 else
563 log_warning "Non-interactive mode: Continuing despite connectivity issues"
564 fi
565 fi
566
567 install_dependencies
568 create_promtail_user
569
570 if ! check_promtail_installed; then
571 install_promtail
572 else
573 log_info "Promtail binary already exists, skipping download"
574 fi
575
576 create_config
577 create_service
578 configure_log_access
579 start_service
580
581 echo
582 echo "=================================="
583 log_success "Promtail installation completed!"
584 echo "=================================="
585 echo
586 echo "Configuration file: $CONFIG_DIR/promtail.yml"
587 echo "Service status: systemctl status promtail"
588 echo "Service logs: journalctl -u promtail -f"
589 echo "Loki endpoint: http://$LOKI_ENDPOINT:$LOKI_PORT"
590 echo
591 echo "To check if logs are being sent to Loki:"
592 echo "curl -G -s \"http://$LOKI_ENDPOINT:$LOKI_PORT/loki/api/v1/query\" --data-urlencode 'query={job=\"system-logs\"}'"
593}
594
595# Execute main function
596main "$@"