Skip to content

Scripts Reference

setup-observability.sh

Initial setup script that installs all dependencies and creates configuration files.

./scripts/setup-observability.sh

What it does:

  • Checks for Homebrew
  • Installs Grafana via Homebrew
  • Downloads Tempo and Loki binaries
  • Creates configuration files for each component
  • Generates start/stop/status scripts
  • Creates .env.observability file

Created directories:

  • ~/.config/device-farm-observability/ - Configuration files
  • ~/.local/share/device-farm-observability/ - Data storage
  • ~/.local/bin/ - Binary files (tempo, loki)

start-observability.sh

Starts all observability services in the background.

./scripts/start-observability.sh

Services started:

Service Port Log File
Tempo 3200 ~/.local/share/device-farm-observability/tempo.log
Loki 3100 ~/.local/share/device-farm-observability/loki.log
Grafana 3001 ~/.local/share/device-farm-observability/grafana.log
View start-observability.sh source code
#!/bin/bash

# Start Device Farm Observability Stack

set -e

CONFIG_DIR="$HOME/.config/device-farm-observability"
DATA_DIR="$HOME/.local/share/device-farm-observability"
PID_DIR="$DATA_DIR/pids"

mkdir -p "$PID_DIR"

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

check_port() {
    if lsof -Pi :$1 -sTCP:LISTEN -t >/dev/null 2>&1; then
        return 0
    fi
    return 1
}

find_binary() {
    local name=$1
    if command -v "$name" &> /dev/null; then
        command -v "$name"
    elif [ -f "$HOME/.local/bin/$name" ]; then
        echo "$HOME/.local/bin/$name"
    else
        echo ""
    fi
}

start_tempo() {
    if check_port 3200; then
        log_warn "Tempo already running on port 3200"
        return
    fi

    local tempo_bin=$(find_binary tempo)
    if [ -z "$tempo_bin" ]; then
        log_error "Tempo binary not found. Run setup-observability.sh first"
        return 1
    fi

    log_info "Starting Tempo..."
    "$tempo_bin" -config.file="$CONFIG_DIR/tempo.yml" > "$DATA_DIR/tempo.log" 2>&1 &
    echo $! > "$PID_DIR/tempo.pid"
    sleep 2

    if check_port 3200; then
        log_info "Tempo started successfully (PID: $(cat $PID_DIR/tempo.pid))"
    else
        log_error "Failed to start Tempo. Check $DATA_DIR/tempo.log"
    fi
}

start_loki() {
    if check_port 3100; then
        log_warn "Loki already running on port 3100"
        return
    fi

    local loki_bin=$(find_binary loki)
    if [ -z "$loki_bin" ]; then
        log_error "Loki binary not found. Run setup-observability.sh first"
        return 1
    fi

    log_info "Starting Loki..."
    "$loki_bin" -config.file="$CONFIG_DIR/loki.yml" > "$DATA_DIR/loki.log" 2>&1 &
    echo $! > "$PID_DIR/loki.pid"
    sleep 2

    if check_port 3100; then
        log_info "Loki started successfully (PID: $(cat $PID_DIR/loki.pid))"
    else
        log_error "Failed to start Loki. Check $DATA_DIR/loki.log"
    fi
}

# Note: Promtail is NOT needed - logs are sent directly via OTLP from hub/node

start_grafana() {
    if check_port 3001; then
        log_warn "Grafana already running on port 3001"
        return
    fi

    log_info "Starting Grafana on port 3001..."

    # Find Grafana home path
    local grafana_home
    if [ -d "/opt/homebrew/share/grafana" ]; then
        grafana_home="/opt/homebrew/share/grafana"
    elif [ -d "/usr/local/share/grafana" ]; then
        grafana_home="/usr/local/share/grafana"
    else
        log_error "Could not find Grafana installation"
        return 1
    fi

    grafana server \
        --homepath "$grafana_home" \
        --config "$grafana_home/conf/defaults.ini" \
        cfg:server.http_port=3001 \
        cfg:paths.data="$DATA_DIR/grafana" \
        cfg:paths.logs="$DATA_DIR/grafana/logs" \
        cfg:auth.anonymous.enabled=true \
        cfg:auth.anonymous.org_role=Admin \
        > "$DATA_DIR/grafana.log" 2>&1 &
    echo $! > "$PID_DIR/grafana.pid"
    sleep 3

    if check_port 3001; then
        log_info "Grafana started successfully (PID: $(cat $PID_DIR/grafana.pid))"
    else
        log_error "Failed to start Grafana. Check $DATA_DIR/grafana.log"
    fi
}

echo ""
echo "╔═══════════════════════════════════════════════════════════╗"
echo "║       Starting Device Farm Observability Stack            ║"
echo "╚═══════════════════════════════════════════════════════════╝"
echo ""

start_tempo
start_loki
start_grafana

echo ""
echo "═══════════════════════════════════════════════════════════"
echo ""
log_info "Observability stack started!"
echo ""
echo "  Grafana:   http://localhost:3001 (anonymous admin access)"
echo "  Tempo:     http://localhost:3200 (traces via OTLP)"
echo "  Loki:      http://localhost:3100 (logs via OTLP)"
echo ""
echo "  Logs are sent directly via OTLP (no file writing)"
echo ""
echo "  Before running Device Farm, source the env file:"
echo "    source .env.observability"
echo ""
echo "  To stop services: ./scripts/stop-observability.sh"
echo ""

stop-observability.sh

Stops all observability services.

./scripts/stop-observability.sh
View stop-observability.sh source code
#!/bin/bash

# Stop Device Farm Observability Stack

PID_DIR="$HOME/.local/share/device-farm-observability/pids"

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }

stop_service() {
    local name=$1
    local pid_file="$PID_DIR/$name.pid"

    if [ -f "$pid_file" ]; then
        local pid=$(cat "$pid_file")
        if kill -0 "$pid" 2>/dev/null; then
            log_info "Stopping $name (PID: $pid)..."
            kill "$pid" 2>/dev/null || true
            rm -f "$pid_file"
        else
            log_warn "$name not running (stale PID file)"
            rm -f "$pid_file"
        fi
    else
        # Try to find and kill by process name
        pkill -f "$name" 2>/dev/null && log_info "Stopped $name" || log_warn "$name not running"
    fi
}

echo ""
echo "Stopping Device Farm Observability Stack..."
echo ""

stop_service "grafana"
stop_service "promtail"
stop_service "loki"
stop_service "tempo"

echo ""
log_info "All services stopped"
echo ""

status-observability.sh

Checks the status of all services.

./scripts/status-observability.sh

Example output:

Device Farm Observability Stack Status
══════════════════════════════════════

  Grafana : running (port 3001)
  Tempo   : running (port 3200)
  Loki    : running (port 3100)
View status-observability.sh source code
#!/bin/bash

# Check status of Device Farm Observability Stack

GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m'

check_service() {
    local name=$1
    local port=$2

    if lsof -Pi :$port -sTCP:LISTEN -t >/dev/null 2>&1; then
        echo -e "  $name: ${GREEN}running${NC} (port $port)"
    else
        echo -e "  $name: ${RED}stopped${NC}"
    fi
}

echo ""
echo "Device Farm Observability Stack Status"
echo "══════════════════════════════════════"
echo ""

check_service "Grafana " 3001
check_service "Tempo   " 3200
check_service "Loki    " 3100

echo ""
echo "Note: Logs are sent directly via OTLP (no Promtail needed)"
echo ""