install-promtail.sh
· 8.0 KiB · Bash
Surowy
#!/bin/bash
# Promtail Installation and Configuration Script for Debian
# Usage: bash -c "$(curl -fsSL <your-gist-url>/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/tcp/$LOKI_ENDPOINT/$LOKI_PORT" 2>/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<service>[^/]+)/.*'
- 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<service>[^/]+)/.*'
- 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 "$@"
| 1 | #!/bin/bash |
| 2 | |
| 3 | # Promtail Installation and Configuration Script for Debian |
| 4 | # Usage: bash -c "$(curl -fsSL <your-gist-url>/install-promtail.sh)" |
| 5 | |
| 6 | set -e |
| 7 | |
| 8 | # Configuration |
| 9 | LOKI_ENDPOINT="loki.pfotenballen.de" |
| 10 | LOKI_PORT="3100" |
| 11 | PROMTAIL_VERSION="2.9.2" |
| 12 | PROMTAIL_USER="promtail" |
| 13 | PROMTAIL_DIR="/opt/promtail" |
| 14 | CONFIG_DIR="/etc/promtail" |
| 15 | LOG_DIR="/var/log/promtail" |
| 16 | |
| 17 | # Colors for output |
| 18 | RED='\033[0;31m' |
| 19 | GREEN='\033[0;32m' |
| 20 | YELLOW='\033[1;33m' |
| 21 | BLUE='\033[0;34m' |
| 22 | NC='\033[0m' # No Color |
| 23 | |
| 24 | # Logging functions |
| 25 | log_info() { |
| 26 | echo -e "${BLUE}[INFO]${NC} $1" |
| 27 | } |
| 28 | |
| 29 | log_success() { |
| 30 | echo -e "${GREEN}[SUCCESS]${NC} $1" |
| 31 | } |
| 32 | |
| 33 | log_warning() { |
| 34 | echo -e "${YELLOW}[WARNING]${NC} $1" |
| 35 | } |
| 36 | |
| 37 | log_error() { |
| 38 | echo -e "${RED}[ERROR]${NC} $1" |
| 39 | } |
| 40 | |
| 41 | # Check if running as root |
| 42 | check_root() { |
| 43 | if [[ $EUID -ne 0 ]]; then |
| 44 | log_error "This script must be run as root" |
| 45 | exit 1 |
| 46 | fi |
| 47 | } |
| 48 | |
| 49 | # Check if promtail is already installed |
| 50 | check_promtail_installed() { |
| 51 | if command -v promtail &> /dev/null || [[ -f "/usr/local/bin/promtail" ]] || [[ -f "$PROMTAIL_DIR/promtail" ]]; then |
| 52 | return 0 |
| 53 | else |
| 54 | return 1 |
| 55 | fi |
| 56 | } |
| 57 | |
| 58 | # Test Loki endpoint connectivity |
| 59 | test_loki_connectivity() { |
| 60 | log_info "Testing connectivity to Loki endpoint: $LOKI_ENDPOINT:$LOKI_PORT" |
| 61 | |
| 62 | if timeout 10 bash -c "</dev/tcp/$LOKI_ENDPOINT/$LOKI_PORT" 2>/dev/null; then |
| 63 | log_success "Successfully connected to $LOKI_ENDPOINT:$LOKI_PORT" |
| 64 | return 0 |
| 65 | else |
| 66 | log_error "Cannot reach $LOKI_ENDPOINT:$LOKI_PORT" |
| 67 | log_error "Please check your network connection and Loki server status" |
| 68 | return 1 |
| 69 | fi |
| 70 | } |
| 71 | |
| 72 | # Install dependencies |
| 73 | install_dependencies() { |
| 74 | log_info "Installing dependencies..." |
| 75 | apt-get update -qq |
| 76 | apt-get install -y wget curl unzip systemd |
| 77 | log_success "Dependencies installed" |
| 78 | } |
| 79 | |
| 80 | # Create promtail user |
| 81 | create_promtail_user() { |
| 82 | if ! id "$PROMTAIL_USER" &>/dev/null; then |
| 83 | log_info "Creating promtail user..." |
| 84 | useradd --system --no-create-home --shell /bin/false $PROMTAIL_USER |
| 85 | log_success "Promtail user created" |
| 86 | else |
| 87 | log_info "Promtail user already exists" |
| 88 | fi |
| 89 | } |
| 90 | |
| 91 | # Download and install promtail |
| 92 | install_promtail() { |
| 93 | log_info "Downloading Promtail v$PROMTAIL_VERSION..." |
| 94 | |
| 95 | # Determine architecture |
| 96 | ARCH=$(uname -m) |
| 97 | case $ARCH in |
| 98 | x86_64) |
| 99 | ARCH_SUFFIX="amd64" |
| 100 | ;; |
| 101 | aarch64) |
| 102 | ARCH_SUFFIX="arm64" |
| 103 | ;; |
| 104 | armv7l) |
| 105 | ARCH_SUFFIX="armv7" |
| 106 | ;; |
| 107 | *) |
| 108 | log_error "Unsupported architecture: $ARCH" |
| 109 | exit 1 |
| 110 | ;; |
| 111 | esac |
| 112 | |
| 113 | # Create directories |
| 114 | mkdir -p $PROMTAIL_DIR |
| 115 | mkdir -p $CONFIG_DIR |
| 116 | mkdir -p $LOG_DIR |
| 117 | |
| 118 | # Download promtail binary |
| 119 | DOWNLOAD_URL="https://github.com/grafana/loki/releases/download/v$PROMTAIL_VERSION/promtail-linux-$ARCH_SUFFIX.zip" |
| 120 | |
| 121 | cd /tmp |
| 122 | wget -q "$DOWNLOAD_URL" -O promtail.zip |
| 123 | unzip -q promtail.zip |
| 124 | |
| 125 | # Install binary |
| 126 | chmod +x promtail-linux-$ARCH_SUFFIX |
| 127 | mv promtail-linux-$ARCH_SUFFIX /usr/local/bin/promtail |
| 128 | |
| 129 | # Set ownership |
| 130 | chown root:root /usr/local/bin/promtail |
| 131 | chown -R $PROMTAIL_USER:$PROMTAIL_USER $CONFIG_DIR $LOG_DIR |
| 132 | |
| 133 | # Cleanup |
| 134 | rm -f promtail.zip |
| 135 | |
| 136 | log_success "Promtail installed successfully" |
| 137 | } |
| 138 | |
| 139 | # Create promtail configuration |
| 140 | create_config() { |
| 141 | log_info "Creating Promtail configuration..." |
| 142 | |
| 143 | # Get the actual hostname |
| 144 | HOSTNAME=$(hostname) |
| 145 | |
| 146 | cat > $CONFIG_DIR/promtail.yml << EOF |
| 147 | server: |
| 148 | http_listen_port: 9080 |
| 149 | grpc_listen_port: 0 |
| 150 | |
| 151 | positions: |
| 152 | filename: /var/lib/promtail/positions.yaml |
| 153 | |
| 154 | clients: |
| 155 | - url: http://$LOKI_ENDPOINT:$LOKI_PORT/loki/api/v1/push |
| 156 | |
| 157 | scrape_configs: |
| 158 | # Direct /var/log/ files (system logs) |
| 159 | - job_name: system-logs |
| 160 | static_configs: |
| 161 | - targets: |
| 162 | - localhost |
| 163 | labels: |
| 164 | job: system-logs |
| 165 | service: system |
| 166 | host: $HOSTNAME |
| 167 | __path__: /var/log/*.log |
| 168 | |
| 169 | # Service-specific logs in subdirectories |
| 170 | - job_name: service-logs |
| 171 | static_configs: |
| 172 | - targets: |
| 173 | - localhost |
| 174 | labels: |
| 175 | job: service-logs |
| 176 | host: $HOSTNAME |
| 177 | __path__: /var/log/*/*.log |
| 178 | pipeline_stages: |
| 179 | - regex: |
| 180 | expression: '/var/log/(?P<service>[^/]+)/.*' |
| 181 | - labels: |
| 182 | service: '{{ .service }}' |
| 183 | |
| 184 | # Recursively capture all nested logs (deeper than one level) |
| 185 | - job_name: nested-service-logs |
| 186 | static_configs: |
| 187 | - targets: |
| 188 | - localhost |
| 189 | labels: |
| 190 | job: nested-service-logs |
| 191 | host: $HOSTNAME |
| 192 | __path__: /var/log/**/*.log |
| 193 | pipeline_stages: |
| 194 | - regex: |
| 195 | expression: '/var/log/(?P<service>[^/]+)/.*' |
| 196 | - labels: |
| 197 | service: '{{ .service }}' |
| 198 | EOF |
| 199 | |
| 200 | # Create positions directory |
| 201 | mkdir -p /var/lib/promtail |
| 202 | chown $PROMTAIL_USER:$PROMTAIL_USER /var/lib/promtail |
| 203 | |
| 204 | # Set proper permissions |
| 205 | chown $PROMTAIL_USER:$PROMTAIL_USER $CONFIG_DIR/promtail.yml |
| 206 | chmod 640 $CONFIG_DIR/promtail.yml |
| 207 | |
| 208 | log_success "Configuration created" |
| 209 | } |
| 210 | |
| 211 | # Create systemd service |
| 212 | create_systemd_service() { |
| 213 | log_info "Creating systemd service..." |
| 214 | |
| 215 | cat > /etc/systemd/system/promtail.service << EOF |
| 216 | [Unit] |
| 217 | Description=Promtail service |
| 218 | Documentation=https://grafana.com/docs/loki/latest/clients/promtail/ |
| 219 | After=network.target |
| 220 | |
| 221 | [Service] |
| 222 | Type=simple |
| 223 | User=$PROMTAIL_USER |
| 224 | ExecStart=/usr/local/bin/promtail -config.file=$CONFIG_DIR/promtail.yml |
| 225 | Restart=always |
| 226 | RestartSec=10 |
| 227 | StandardOutput=journal |
| 228 | StandardError=journal |
| 229 | SyslogIdentifier=promtail |
| 230 | |
| 231 | [Install] |
| 232 | WantedBy=multi-user.target |
| 233 | EOF |
| 234 | |
| 235 | systemctl daemon-reload |
| 236 | log_success "Systemd service created" |
| 237 | } |
| 238 | |
| 239 | # Add promtail user to adm group for log access |
| 240 | configure_log_access() { |
| 241 | log_info "Configuring log file access..." |
| 242 | usermod -a -G adm $PROMTAIL_USER |
| 243 | log_success "Log access configured" |
| 244 | } |
| 245 | |
| 246 | # Start and enable service |
| 247 | start_service() { |
| 248 | log_info "Starting Promtail service..." |
| 249 | |
| 250 | systemctl enable promtail |
| 251 | systemctl start promtail |
| 252 | |
| 253 | # Wait a moment and check status |
| 254 | sleep 2 |
| 255 | |
| 256 | if systemctl is-active --quiet promtail; then |
| 257 | log_success "Promtail service is running" |
| 258 | log_info "Service status:" |
| 259 | systemctl status promtail --no-pager -l |
| 260 | else |
| 261 | log_error "Failed to start Promtail service" |
| 262 | log_error "Check logs with: journalctl -u promtail -f" |
| 263 | exit 1 |
| 264 | fi |
| 265 | } |
| 266 | |
| 267 | # Main installation process |
| 268 | main() { |
| 269 | echo "==================================" |
| 270 | echo " Promtail Installation Script " |
| 271 | echo "==================================" |
| 272 | echo |
| 273 | |
| 274 | check_root |
| 275 | |
| 276 | if check_promtail_installed; then |
| 277 | log_warning "Promtail appears to be already installed" |
| 278 | echo "Existing installation found. Do you want to continue and reconfigure? (y/N)" |
| 279 | read -r response |
| 280 | if [[ ! "$response" =~ ^[Yy]$ ]]; then |
| 281 | log_info "Installation cancelled" |
| 282 | exit 0 |
| 283 | fi |
| 284 | fi |
| 285 | |
| 286 | # Test Loki connectivity first |
| 287 | if ! test_loki_connectivity; then |
| 288 | echo "Do you want to continue anyway? (y/N)" |
| 289 | read -r response |
| 290 | if [[ ! "$response" =~ ^[Yy]$ ]]; then |
| 291 | log_info "Installation cancelled" |
| 292 | exit 1 |
| 293 | fi |
| 294 | fi |
| 295 | |
| 296 | install_dependencies |
| 297 | create_promtail_user |
| 298 | |
| 299 | if ! check_promtail_installed; then |
| 300 | install_promtail |
| 301 | else |
| 302 | log_info "Promtail binary already exists, skipping download" |
| 303 | fi |
| 304 | |
| 305 | create_config |
| 306 | create_systemd_service |
| 307 | configure_log_access |
| 308 | start_service |
| 309 | |
| 310 | echo |
| 311 | echo "==================================" |
| 312 | log_success "Promtail installation completed!" |
| 313 | echo "==================================" |
| 314 | echo |
| 315 | echo "Configuration file: $CONFIG_DIR/promtail.yml" |
| 316 | echo "Service status: systemctl status promtail" |
| 317 | echo "Service logs: journalctl -u promtail -f" |
| 318 | echo "Loki endpoint: http://$LOKI_ENDPOINT:$LOKI_PORT" |
| 319 | echo |
| 320 | echo "To check if logs are being sent to Loki:" |
| 321 | echo "curl -G -s \"http://$LOKI_ENDPOINT:$LOKI_PORT/loki/api/v1/query\" --data-urlencode 'query={job=\"system-logs\"}'" |
| 322 | } |
| 323 | |
| 324 | # Execute main function |
| 325 | main "$@" |