mirror of
https://github.com/kossakovsky/n8n-install.git
synced 2026-03-07 14:23:08 +00:00
232 lines
8.7 KiB
Bash
232 lines
8.7 KiB
Bash
#!/bin/bash
|
|
# =============================================================================
|
|
# telemetry.sh - Anonymous telemetry for n8n-install
|
|
# =============================================================================
|
|
# Sends anonymous usage statistics to help improve the project.
|
|
# No personal data is collected. Users can opt-out by setting:
|
|
# SCARF_ANALYTICS=false or DO_NOT_TRACK=1
|
|
#
|
|
# Depends on: utils.sh (must be sourced first for ENV_FILE, PROJECT_ROOT)
|
|
#
|
|
# Functions:
|
|
# get_installation_id() - Get or generate persistent installation ID
|
|
# get_os_type() - Detect OS type
|
|
# send_telemetry() - Send anonymous telemetry event
|
|
# set_telemetry_stage() - Set current stage for error tracking
|
|
# send_error_telemetry() - Send error telemetry event
|
|
# setup_error_telemetry_trap() - Setup global ERR trap
|
|
# save_installation_id() - Save installation ID to .env
|
|
#
|
|
# Usage: source "$SCRIPT_DIR/telemetry.sh"
|
|
# =============================================================================
|
|
|
|
# Scarf endpoint for anonymous telemetry
|
|
SCARF_ENDPOINT="https://kossakovsky.gateway.scarf.sh/n8n-install"
|
|
|
|
#=============================================================================
|
|
# INSTALLATION ID
|
|
#=============================================================================
|
|
|
|
# Get or generate installation ID (persistent across sessions)
|
|
# Usage: id=$(get_installation_id)
|
|
# Priority: 1) exported env var, 2) .env file, 3) generate new
|
|
get_installation_id() {
|
|
# First check if ID is already in environment (exported from parent process)
|
|
# This ensures consistency when called multiple times before .env exists
|
|
if [[ -n "${INSTALLATION_ID:-}" ]]; then
|
|
echo "$INSTALLATION_ID"
|
|
return 0
|
|
fi
|
|
|
|
# Then check .env file for existing ID
|
|
if [[ -f "$ENV_FILE" ]]; then
|
|
local existing_id
|
|
existing_id=$(grep "^INSTALLATION_ID=" "$ENV_FILE" 2>/dev/null | cut -d'=' -f2- | tr -d '"' | tr -d "'")
|
|
if [[ -n "$existing_id" ]]; then
|
|
echo "$existing_id"
|
|
return 0
|
|
fi
|
|
fi
|
|
|
|
# Generate new ID (12 char hex = 6 bytes)
|
|
local new_id
|
|
new_id=$(od -An -tx1 -N6 /dev/urandom | tr -d ' \n')
|
|
|
|
# Save to .env if file exists
|
|
if [[ -f "$ENV_FILE" ]]; then
|
|
if grep -q "^INSTALLATION_ID=" "$ENV_FILE" 2>/dev/null; then
|
|
sed -i.bak "s/^INSTALLATION_ID=.*/INSTALLATION_ID=\"${new_id}\"/" "$ENV_FILE"
|
|
rm -f "${ENV_FILE}.bak"
|
|
else
|
|
echo "INSTALLATION_ID=\"${new_id}\"" >> "$ENV_FILE"
|
|
fi
|
|
fi
|
|
|
|
echo "$new_id"
|
|
}
|
|
|
|
# Save installation ID to .env file
|
|
# Usage: save_installation_id
|
|
# Priority: 1) exported from parent, 2) existing .env, 3) generate new
|
|
# Note: Requires write_env_var from utils.sh
|
|
save_installation_id() {
|
|
local output_file="${1:-$ENV_FILE}"
|
|
|
|
# Priority: exported var > existing .env value > generate new
|
|
local install_id="${INSTALLATION_ID:-}"
|
|
|
|
if [[ -z "$install_id" && -f "$output_file" ]]; then
|
|
install_id=$(grep "^INSTALLATION_ID=" "$output_file" 2>/dev/null | cut -d'=' -f2- | tr -d '"' | tr -d "'")
|
|
fi
|
|
|
|
if [[ -z "$install_id" ]]; then
|
|
# Generate new ID for existing installations upgrading from pre-telemetry version
|
|
install_id=$(od -An -tx1 -N6 /dev/urandom | tr -d ' \n')
|
|
fi
|
|
|
|
write_env_var "INSTALLATION_ID" "$install_id" "$output_file"
|
|
}
|
|
|
|
#=============================================================================
|
|
# OS DETECTION
|
|
#=============================================================================
|
|
|
|
# Detect OS type
|
|
# Usage: os=$(get_os_type)
|
|
get_os_type() {
|
|
if [[ -f /etc/os-release ]]; then
|
|
. /etc/os-release
|
|
echo "${ID:-linux}-${VERSION_ID:-unknown}"
|
|
elif [[ "$(uname)" == "Darwin" ]]; then
|
|
echo "macos-$(sw_vers -productVersion 2>/dev/null || echo 'unknown')"
|
|
else
|
|
echo "$(uname -s | tr '[:upper:]' '[:lower:]')-unknown"
|
|
fi
|
|
}
|
|
|
|
#=============================================================================
|
|
# TELEMETRY EVENTS
|
|
#=============================================================================
|
|
|
|
# Send anonymous telemetry event
|
|
# Usage: send_telemetry "install_start"
|
|
# send_telemetry "install_complete" "$COMPOSE_PROFILES"
|
|
# send_telemetry "update_start"
|
|
# send_telemetry "update_complete" "$COMPOSE_PROFILES"
|
|
# Arguments:
|
|
# $1 - event_type: "install_start", "install_complete", "update_start", "update_complete"
|
|
# $2 - services (optional): comma-separated list of selected profiles (for *_complete events)
|
|
# When provided, sends a separate request for each service to enable per-service analytics.
|
|
# Note: To get installation ID, call get_installation_id directly before this function
|
|
send_telemetry() {
|
|
local event_type="$1"
|
|
local services="${2:-}"
|
|
|
|
# Load environment (for SCARF_ANALYTICS check and INSTALLATION_ID)
|
|
[[ -f "$ENV_FILE" ]] && source "$ENV_FILE" 2>/dev/null
|
|
|
|
# Get installation ID and OS
|
|
local install_id
|
|
install_id=$(get_installation_id)
|
|
local os_type
|
|
os_type=$(get_os_type)
|
|
|
|
# Opt-out check: respect SCARF_ANALYTICS and DO_NOT_TRACK
|
|
if [[ "${SCARF_ANALYTICS:-true}" == "false" ]] || [[ "${DO_NOT_TRACK:-0}" == "1" ]]; then
|
|
return 0
|
|
fi
|
|
|
|
# Get version from VERSION file
|
|
local version="unknown"
|
|
if [[ -f "$PROJECT_ROOT/VERSION" ]]; then
|
|
version=$(cat "$PROJECT_ROOT/VERSION" | tr -d '\n\r')
|
|
fi
|
|
|
|
# Build base URL with query parameters
|
|
local base_url="${SCARF_ENDPOINT}?event=${event_type}&version=${version}&id=${install_id}&os=${os_type}"
|
|
|
|
if [[ -n "$services" ]]; then
|
|
# Split services by comma and send individual request for each service
|
|
# This allows Scarf to track usage statistics per service
|
|
local service
|
|
IFS=',' read -ra service_array <<< "$services"
|
|
for service in "${service_array[@]}"; do
|
|
# Trim whitespace
|
|
service=$(echo "$service" | xargs)
|
|
[[ -z "$service" ]] && continue
|
|
# Send telemetry for this service in background
|
|
curl -sf --connect-timeout 2 --max-time 2 "${base_url}&services=${service}" >/dev/null 2>&1 &
|
|
done
|
|
else
|
|
# No services specified, send single event
|
|
curl -sf --connect-timeout 2 --max-time 2 "$base_url" >/dev/null 2>&1 &
|
|
fi
|
|
}
|
|
|
|
#=============================================================================
|
|
# ERROR TELEMETRY
|
|
#=============================================================================
|
|
# Tracks installation/update failures with stage and exit code.
|
|
# Uses same opt-out as regular telemetry (SCARF_ANALYTICS=false or DO_NOT_TRACK=1)
|
|
|
|
# Set current telemetry stage for error tracking
|
|
# Usage: set_telemetry_stage "system_prep"
|
|
set_telemetry_stage() {
|
|
export TELEMETRY_STAGE="$1"
|
|
}
|
|
|
|
# Send error telemetry event (called by trap handler)
|
|
# Usage: send_error_telemetry 1
|
|
# Arguments:
|
|
# $1 - exit_code: The exit code that triggered the error
|
|
send_error_telemetry() {
|
|
local exit_code="${1:-1}"
|
|
local stage="${TELEMETRY_STAGE:-unknown}"
|
|
|
|
# Prevent duplicate sends
|
|
[[ "${TELEMETRY_ERROR_SENT:-0}" == "1" ]] && return 0
|
|
export TELEMETRY_ERROR_SENT=1
|
|
|
|
# Load environment (for SCARF_ANALYTICS check)
|
|
[[ -f "$ENV_FILE" ]] && source "$ENV_FILE" 2>/dev/null
|
|
|
|
# Opt-out check: respect SCARF_ANALYTICS and DO_NOT_TRACK
|
|
[[ "${SCARF_ANALYTICS:-true}" == "false" || "${DO_NOT_TRACK:-0}" == "1" ]] && return 0
|
|
|
|
# Determine event type based on stage prefix
|
|
local event_type="install_error"
|
|
[[ "$stage" == update_* || "$stage" == git_* ]] && event_type="update_error"
|
|
|
|
# Get installation ID and OS
|
|
local install_id
|
|
install_id=$(get_installation_id)
|
|
local os_type
|
|
os_type=$(get_os_type)
|
|
|
|
# Get version from VERSION file
|
|
local version="unknown"
|
|
[[ -f "$PROJECT_ROOT/VERSION" ]] && version=$(cat "$PROJECT_ROOT/VERSION" | tr -d '\n\r')
|
|
|
|
# Build URL with error-specific parameters
|
|
local url="${SCARF_ENDPOINT}?event=${event_type}&version=${version}&id=${install_id}&os=${os_type}&stage=${stage}&exit_code=${exit_code}"
|
|
|
|
# Send telemetry in background with short timeout (non-blocking, silent)
|
|
curl -sf --connect-timeout 2 --max-time 2 "$url" >/dev/null 2>&1 &
|
|
}
|
|
|
|
# Internal trap handler for ERR signal
|
|
_telemetry_error_handler() {
|
|
local exit_code=$?
|
|
# Only send if we actually have an error (exit_code > 0)
|
|
[[ $exit_code -gt 0 ]] && send_error_telemetry "$exit_code"
|
|
# Re-exit with the original code (important for set -e behavior)
|
|
exit $exit_code
|
|
}
|
|
|
|
# Setup global ERR trap for error telemetry
|
|
# Usage: setup_error_telemetry_trap
|
|
# Note: Only call this in top-level orchestrator scripts (install.sh, apply_update.sh, update.sh)
|
|
setup_error_telemetry_trap() {
|
|
trap '_telemetry_error_handler' ERR
|
|
}
|