|
1 | 1 | #!/bin/bash |
2 | | -# View logs for specific environment or all containers |
3 | | -# Supports following logs in real-time |
| 2 | +# View logs for containers on Application Server |
| 3 | +# Runs from LOCAL MACHINE and SSHs to Application Server |
| 4 | +# Product-agnostic version - uses axon.config.yml |
4 | 5 |
|
5 | | -# Colors for output |
| 6 | +set -e |
| 7 | + |
| 8 | +# Colors |
6 | 9 | RED='\033[0;31m' |
7 | 10 | GREEN='\033[0;32m' |
8 | 11 | YELLOW='\033[1;33m' |
9 | 12 | BLUE='\033[0;34m' |
10 | | -NC='\033[0m' # No Color |
| 13 | +CYAN='\033[0;36m' |
| 14 | +NC='\033[0m' |
| 15 | + |
| 16 | +# Script directory |
| 17 | +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 18 | +MODULE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" |
| 19 | +# Use current working directory for PRODUCT_ROOT (where config/Dockerfile live) |
| 20 | +PRODUCT_ROOT="$PWD" |
| 21 | + |
| 22 | +# Default configuration file |
| 23 | +CONFIG_FILE="${PRODUCT_ROOT}/axon.config.yml" |
| 24 | +ENVIRONMENT="" |
| 25 | +FOLLOW=false |
| 26 | +LINES="50" |
| 27 | +SINCE="" |
11 | 28 |
|
12 | 29 | # Parse arguments |
13 | | -ENVIRONMENT=${1} |
14 | | -FOLLOW=${2} |
15 | | -PRODUCT_NAME=${3} |
| 30 | +while [[ $# -gt 0 ]]; do |
| 31 | + case $1 in |
| 32 | + -c|--config) |
| 33 | + CONFIG_FILE="$2" |
| 34 | + shift 2 |
| 35 | + ;; |
| 36 | + --follow|-f) |
| 37 | + FOLLOW=true |
| 38 | + shift |
| 39 | + ;; |
| 40 | + -n|--lines|--tail) |
| 41 | + LINES="$2" |
| 42 | + shift 2 |
| 43 | + ;; |
| 44 | + --since) |
| 45 | + SINCE="$2" |
| 46 | + shift 2 |
| 47 | + ;; |
| 48 | + -h|--help) |
| 49 | + echo "Usage: $0 <environment> [OPTIONS]" |
| 50 | + echo "" |
| 51 | + echo "View container logs for specified environment." |
| 52 | + echo "" |
| 53 | + echo "OPTIONS:" |
| 54 | + echo " -c, --config FILE Specify config file (default: axon.config.yml)" |
| 55 | + echo " -f, --follow Follow log output (stream in real-time)" |
| 56 | + echo " -n, --lines N Number of lines to show (default: 50)" |
| 57 | + echo " --tail N Same as --lines" |
| 58 | + echo " --since DURATION Show logs since duration (e.g., 1h, 30m)" |
| 59 | + echo " -h, --help Show this help message" |
| 60 | + echo "" |
| 61 | + echo "Arguments:" |
| 62 | + echo " environment Environment to check logs for" |
| 63 | + echo "" |
| 64 | + echo "Examples:" |
| 65 | + echo " $0 production # Last 50 lines" |
| 66 | + echo " $0 staging --follow # Follow logs in real-time" |
| 67 | + echo " $0 production --lines 100 # Last 100 lines" |
| 68 | + echo " $0 staging --since 1h # Logs from last hour" |
| 69 | + exit 0 |
| 70 | + ;; |
| 71 | + -*) |
| 72 | + echo -e "${RED}Error: Unknown option: $1${NC}" |
| 73 | + echo "Use --help for usage information" |
| 74 | + exit 1 |
| 75 | + ;; |
| 76 | + *) |
| 77 | + # Positional argument |
| 78 | + if [ -z "$ENVIRONMENT" ]; then |
| 79 | + ENVIRONMENT="$1" |
| 80 | + else |
| 81 | + echo -e "${RED}Error: Too many positional arguments${NC}" |
| 82 | + echo "Use --help for usage information" |
| 83 | + exit 1 |
| 84 | + fi |
| 85 | + shift |
| 86 | + ;; |
| 87 | + esac |
| 88 | +done |
16 | 89 |
|
17 | | -# Show usage if no arguments |
| 90 | +# Validate environment provided |
18 | 91 | if [ -z "$ENVIRONMENT" ]; then |
19 | | - echo -e "${BLUE}View Docker Container Logs${NC}" |
20 | | - echo "" |
21 | | - echo "Usage:" |
22 | | - echo " $0 <environment> [follow] [product_name]" |
23 | | - echo "" |
24 | | - echo "Arguments:" |
25 | | - echo " environment Any environment from axon.config.yml or 'all'" |
26 | | - echo " follow Optional: 'follow' to stream logs in real-time" |
27 | | - echo " product_name Optional: filter by specific product" |
28 | | - echo "" |
29 | | - echo "Examples:" |
30 | | - echo " $0 production # Show last 50 lines" |
31 | | - echo " $0 staging # Show last 50 lines" |
32 | | - echo " $0 development # Show last 50 lines (custom env)" |
33 | | - echo " $0 all # Show all environments" |
34 | | - echo " $0 production follow # Follow logs in real-time" |
35 | | - exit 0 |
| 92 | + echo -e "${RED}Error: Environment is required${NC}" |
| 93 | + echo "Usage: $0 <environment> [OPTIONS]" |
| 94 | + echo "Use --help for more information" |
| 95 | + exit 1 |
36 | 96 | fi |
37 | 97 |
|
38 | | -# Note: Environment validation is not needed here |
39 | | -# The script accepts any environment name defined in axon.config.yml or "all" |
| 98 | +# Make CONFIG_FILE absolute path if it's relative |
| 99 | +if [[ "$CONFIG_FILE" != /* ]]; then |
| 100 | + CONFIG_FILE="${PRODUCT_ROOT}/${CONFIG_FILE}" |
| 101 | +fi |
40 | 102 |
|
41 | | -# Check if Docker is running |
42 | | -if ! docker info &> /dev/null 2>&1; then |
43 | | - echo -e "${RED}Error: Docker is not running${NC}" |
44 | | - exit 1 |
| 103 | +# Validate config file exists |
| 104 | +if [ ! -f "$CONFIG_FILE" ]; then |
| 105 | + echo -e "${RED}Error: Config file not found: $CONFIG_FILE${NC}" |
| 106 | + exit 1 |
45 | 107 | fi |
46 | 108 |
|
47 | | -# Function to show logs for an environment |
48 | | -show_logs() { |
49 | | - local ENV=$1 |
| 109 | +# Source config parser |
| 110 | +source "$MODULE_DIR/lib/config-parser.sh" |
50 | 111 |
|
51 | | - # Find the most recent container for this environment (sorted by name which includes timestamp) |
52 | | - local CONTAINER=$(docker ps -a --filter "name=${PRODUCT_NAME}-${ENV}-" --format '{{.Names}}' | sort -r | head -n 1) |
| 112 | +# Load product name |
| 113 | +PRODUCT_NAME=$(parse_yaml_key "product.name" "") |
53 | 114 |
|
54 | | - # Check if container exists |
55 | | - if [ -z "$CONTAINER" ]; then |
56 | | - echo -e "${YELLOW}Warning: No ${ENV} container found (${PRODUCT_NAME}-${ENV})${NC}" |
57 | | - return 1 |
58 | | - fi |
| 115 | +if [ -z "$PRODUCT_NAME" ]; then |
| 116 | + echo -e "${RED}Error: Product name not configured${NC}" |
| 117 | + exit 1 |
| 118 | +fi |
59 | 119 |
|
60 | | - echo -e "${BLUE}Logs for ${ENV} environment:${NC}" |
61 | | - echo -e "${BLUE}Container: ${CONTAINER}${NC}" |
62 | | - echo "" |
| 120 | +# Get Application Server SSH details |
| 121 | +APPLICATION_SERVER_HOST=$(parse_yaml_key ".servers.application.host" "") |
| 122 | +APPLICATION_SERVER_USER=$(parse_yaml_key ".servers.application.user" "") |
| 123 | +APPLICATION_SERVER_SSH_KEY=$(parse_yaml_key ".servers.application.ssh_key" "") |
| 124 | +APPLICATION_SERVER_SSH_KEY="${APPLICATION_SERVER_SSH_KEY/#\~/$HOME}" |
63 | 125 |
|
64 | | - if [ "$FOLLOW" == "follow" ]; then |
65 | | - echo -e "${GREEN}Following logs (Ctrl+C to exit)...${NC}" |
66 | | - echo "" |
67 | | - docker logs -f --tail=100 "$CONTAINER" |
68 | | - else |
69 | | - docker logs --tail=50 "$CONTAINER" |
70 | | - fi |
71 | | -} |
72 | | - |
73 | | -# Main logic |
74 | | -if [ "$ENVIRONMENT" == "all" ]; then |
75 | | - echo -e "${BLUE}==================================================${NC}" |
76 | | - echo -e "${BLUE}All Container Logs${NC}" |
77 | | - echo -e "${BLUE}==================================================${NC}" |
78 | | - echo "" |
79 | | - |
80 | | - if [ "$FOLLOW" == "follow" ]; then |
81 | | - echo -e "${GREEN}Following all logs (Ctrl+C to exit)...${NC}" |
82 | | - echo "" |
83 | | - # Get all containers and follow them |
84 | | - CONTAINERS=$(docker ps -a --filter "name=${PRODUCT_NAME}-" --format '{{.Names}}' | sort -r) |
85 | | - if [ -z "$CONTAINERS" ]; then |
86 | | - echo -e "${YELLOW}No containers found${NC}" |
87 | | - exit 0 |
88 | | - fi |
89 | | - |
90 | | - # Follow logs from all containers (Docker will multiplex them) |
91 | | - docker logs -f --tail=100 $(echo $CONTAINERS | tr '\n' ' ') |
92 | | - else |
93 | | - # Show production logs |
94 | | - show_logs "production" |
| 126 | +if [ -z "$APPLICATION_SERVER_HOST" ]; then |
| 127 | + echo -e "${RED}Error: Application Server host not configured${NC}" |
| 128 | + exit 1 |
| 129 | +fi |
| 130 | + |
| 131 | +if [ ! -f "$APPLICATION_SERVER_SSH_KEY" ]; then |
| 132 | + echo -e "${RED}Error: SSH key not found: $APPLICATION_SERVER_SSH_KEY${NC}" |
| 133 | + exit 1 |
| 134 | +fi |
| 135 | + |
| 136 | +APP_SERVER="${APPLICATION_SERVER_USER}@${APPLICATION_SERVER_HOST}" |
| 137 | + |
| 138 | +# Build container filter |
| 139 | +CONTAINER_FILTER="${PRODUCT_NAME}-${ENVIRONMENT}" |
| 140 | + |
| 141 | +echo -e "${BLUE}==================================================${NC}" |
| 142 | +echo -e "${BLUE}Container Logs - ${PRODUCT_NAME}${NC}" |
| 143 | +echo -e "${BLUE}Environment: ${ENVIRONMENT^}${NC}" |
| 144 | +echo -e "${BLUE}On Application Server: ${APP_SERVER}${NC}" |
| 145 | +echo -e "${BLUE}==================================================${NC}" |
| 146 | +echo "" |
| 147 | + |
| 148 | +# Find the most recent container for this environment |
| 149 | +CONTAINER=$(ssh -i "$APPLICATION_SERVER_SSH_KEY" "$APP_SERVER" \ |
| 150 | + "docker ps -a --filter 'name=${CONTAINER_FILTER}-' --format '{{.Names}}' | sort -r | head -n 1") |
| 151 | + |
| 152 | +# Check if container exists |
| 153 | +if [ -z "$CONTAINER" ]; then |
| 154 | + echo -e "${YELLOW}Warning: No container found for ${ENVIRONMENT} environment${NC}" |
| 155 | + echo -e "${YELLOW}Looking for containers matching: ${CONTAINER_FILTER}-${NC}" |
95 | 156 | echo "" |
96 | | - echo -e "${BLUE}---------------------------------------------------${NC}" |
| 157 | + echo "Available containers:" |
| 158 | + ssh -i "$APPLICATION_SERVER_SSH_KEY" "$APP_SERVER" \ |
| 159 | + "docker ps -a --format 'table {{.Names}}\t{{.Status}}' | grep ${PRODUCT_NAME} || echo ' None found'" |
| 160 | + exit 1 |
| 161 | +fi |
| 162 | + |
| 163 | +echo -e "${CYAN}Container: ${CONTAINER}${NC}" |
| 164 | +echo "" |
| 165 | + |
| 166 | +# Build docker logs command |
| 167 | +LOGS_CMD="docker logs" |
| 168 | + |
| 169 | +if [ "$FOLLOW" = true ]; then |
| 170 | + LOGS_CMD="$LOGS_CMD -f" |
| 171 | + echo -e "${GREEN}Following logs (Ctrl+C to exit)...${NC}" |
97 | 172 | echo "" |
98 | | - # Show staging logs |
99 | | - show_logs "staging" |
100 | | - fi |
101 | | -else |
102 | | - show_logs "$ENVIRONMENT" |
103 | 173 | fi |
| 174 | + |
| 175 | +if [ -n "$SINCE" ]; then |
| 176 | + LOGS_CMD="$LOGS_CMD --since $SINCE" |
| 177 | +fi |
| 178 | + |
| 179 | +LOGS_CMD="$LOGS_CMD --tail $LINES \"$CONTAINER\"" |
| 180 | + |
| 181 | +# Execute docker logs command on Application Server |
| 182 | +ssh -i "$APPLICATION_SERVER_SSH_KEY" "$APP_SERVER" "$LOGS_CMD" |
0 commit comments