Index: /branches/amp_4_0/platform/config/syslog.conf
===================================================================
--- /branches/amp_4_0/platform/config/syslog.conf	(revision 2627)
+++ /branches/amp_4_0/platform/config/syslog.conf	(working copy)
@@ -263,6 +263,55 @@
         }
       }
 
+      # --- GEOIP INTEGRATION START ---
+      # Apply GeoIP on client_ip if it exists
+      if [client_ip] {
+        geoip {
+          source => "client_ip"
+          target => "client_geoip" # Use a distinct target for client IP geoip
+          tag_on_failure => ["_geoip_client_failed"]
+        }
+      }
+      # Handle cases where client_geoip.location is missing
+      # Fallback lat, lon - Array Networks Bengaluru office.
+      if [client_ip] and ![client_geoip][location] { # Only fallback if client_ip was present
+        mutate {
+          add_field => {
+            "[client_geoip][city_name]" => "Unknown"
+            "[client_geoip][country_name]" => "Unresolved"
+            "[client_geoip][location][lat]" => "12.9254143647407"
+            "[client_geoip][location][lon]" => "77.63149239905859"
+          }
+        }
+        mutate {
+          add_tag => ["_geoip_client_unresolved"]
+        }
+      }
+
+      # Optionally, apply GeoIP on destination_ip if it exists
+      if [destination_ip] {
+        geoip {
+          source => "destination_ip"
+          target => "destination_geoip" # Use a distinct target for destination IP geoip
+          tag_on_failure => ["_geoip_destination_failed"]
+        }
+      }
+      # Handle cases where destination_geoip.location is missing
+      if [destination_ip] and ![destination_geoip][location] { # Only fallback if destination_ip was present
+        mutate {
+          add_field => {
+            "[destination_geoip][city_name]" => "Unknown"
+            "[destination_geoip][country_name]" => "Unresolved"
+            "[destination_geoip][location][lat]" => "0.0"
+            "[destination_geoip][location][lon]" => "0.0"
+          }
+        }
+        mutate {
+          add_tag => ["_geoip_destination_unresolved"]
+        }
+      }
+      # --- GEOIP INTEGRATION END ---
+
       if [device_ip] {
         jdbc_streaming {
           jdbc_driver_library => "/etc/logstash/jdbc_drivers/postgresql-42.7.5.jar"
Index: /branches/amp_4_0/platform/tools/install_grafana.sh
===================================================================
--- /branches/amp_4_0/platform/tools/install_grafana.sh	(revision 2627)
+++ /branches/amp_4_0/platform/tools/install_grafana.sh	(working copy)
@@ -10,7 +10,7 @@
 INFLUXDB_ORG="AN"
 INFLUXDB_BUCKET="AMP"
 INFLUXDB_TOKEN_FILE="/opt/influxdb2_token.toml"
-LOG_FILE="/var/log/configure_grafana.log"
+LOG_FILE="/var/log/install_grafana.log"
 
 #---------------------------
 # Logging and Helpers
@@ -28,7 +28,7 @@
 #---------------------------
 read_influxdb_token() {
   [[ -f "$INFLUXDB_TOKEN_FILE" ]] || error "InfluxDB token file not found: $INFLUXDB_TOKEN_FILE"
-  INFLUXDB_TOKEN=$(awk -F'=' '/token/ {gsub(/[ "\r]/, "", $2); print $2}' "$INFLUXDB_TOKEN_FILE")
+  INFLUXDB_TOKEN=$(sed -nE 's/^[[:space:]]*token[[:space:]]*=[[:space:]]*"([^"]*)".*$/\1/p' "$INFLUXDB_TOKEN_FILE")
   [[ -n "$INFLUXDB_TOKEN" ]] || error "Failed to read InfluxDB token from file."
   info "Read InfluxDB token."
 }
@@ -66,7 +66,7 @@
     grafana-cli admin reset-admin-password "$GRAFANA_PASSWORD" >> "$LOG_FILE" 2>&1 || error "Failed to reset admin password via CLI."
     info "Grafana admin password set to '$GRAFANA_PASSWORD'"
   else
-    warn "grafana-cli not found, skipping admin password reset."
+    log "[WARN] grafana-cli not found, skipping admin password reset."
   fi
 }
 
@@ -74,20 +74,51 @@
 # Create API Token
 #---------------------------
 create_api_token() {
-  info "Creating Grafana API token..."
-  RESPONSE=$(curl -s -X POST http://localhost:3000/api/auth/keys \
+  info "Creating Grafana service account and API token..."
+
+  # Create a service account
+  RESPONSE=$(curl -s -w "%{http_code}" -o /tmp/grafana_serviceaccount_response.txt \
+    -X POST http://localhost:3000/api/serviceaccounts \
     -H "Content-Type: application/json" \
-    -H "Authorization: Basic $(echo -n "$GRAFANA_USER:$GRAFANA_PASSWORD" | base64)" \
-    -d '{"name": "InfluxDB API Token", "role": "Admin"}')
+    -H "Authorization: Basic $(printf '%s' "$GRAFANA_USER:$GRAFANA_PASSWORD" | base64)" \
+    -d '{"name": "InfluxDB Service Account", "role": "Admin"}')
 
-  TOKEN=$(echo "$RESPONSE" | jq -r '.token')
+  BODY=$(cat /tmp/grafana_serviceaccount_response.txt)
+  CODE=$(echo "$RESPONSE" | tail -n1)
+
+  if [[ ! "$CODE" =~ 20[01] ]]; then
+    echo "$BODY" >> "$LOG_FILE"
+    error "Failed to create service account (HTTP $CODE). Response: $BODY"
+  fi
+
+  # Extract service account ID
+  SERVICE_ACCOUNT_ID=$(echo "$BODY" | jq -r '.id')
+  [[ -n "$SERVICE_ACCOUNT_ID" && "$SERVICE_ACCOUNT_ID" != "null" ]] || error "Failed to extract service account ID. Response: $BODY"
+
+  info "Service account created with ID: $SERVICE_ACCOUNT_ID"
+
+  # Create a token for the service account
+  RESPONSE=$(curl -s -w "%{http_code}" -o /tmp/grafana_token_response.txt \
+    -X POST http://localhost:3000/api/serviceaccounts/"$SERVICE_ACCOUNT_ID"/tokens \
+    -H "Content-Type: application/json" \
+    -H "Authorization: Basic $(printf '%s' "$GRAFANA_USER:$GRAFANA_PASSWORD" | base64)" \
+    -d '{"name": "InfluxDB API Token"}')
+
+  BODY=$(cat /tmp/grafana_token_response.txt)
+  CODE=$(echo "$RESPONSE" | tail -n1)
+
+  if [[ ! "$CODE" =~ 20[01] ]]; then
+    echo "$BODY" >> "$LOG_FILE"
+    error "Failed to create API token (HTTP $CODE). Response: $BODY"
+  fi
+
+  # Extract the token
+  TOKEN=$(echo "$BODY" | jq -r '.key')
   if [[ "$TOKEN" == "null" || -z "$TOKEN" ]]; then
-    error "Failed to create API token. Response: $RESPONSE"
+    error "Failed to extract API token. Response: $BODY"
   fi
 
   echo "$TOKEN" | tee /opt/grafana_token >> "$LOG_FILE"
-
-    # Secure the token file with restrictive permissions
   chmod 600 /opt/grafana_token
   chown root:root /opt/grafana_token
   info "API token created and stored in /opt/grafana_token."
@@ -98,17 +129,45 @@
 #---------------------------
 add_influxdb_datasource() {
   command_exists curl || error "curl is required but not installed."
+  command_exists jq || error "jq is required but not installed."
   read_influxdb_token
 
-  # Wait for Grafana
-  info "Waiting for Grafana API to be ready..."
+  # Validate token format
+  if [[ ! "$INFLUXDB_TOKEN" =~ ^[A-Za-z0-9\+\/_-]+=*$ ]]; then
+    error "Invalid InfluxDB token format: $INFLUXDB_TOKEN"
+  fi
+  info "InfluxDB token validated."
+
+  # Wait for Grafana API with timeout (60 seconds)
+  info "Waiting for Grafana API to be ready (timeout 60s)..."
+  TIMEOUT=60
+  COUNT=0
   until curl -s http://localhost:3000/api/health | grep -q "database"; do
     sleep 2
+    ((COUNT+=2))
     echo -n "."
+    if [[ $COUNT -ge $TIMEOUT ]]; then
+      error "Grafana API not ready after ${TIMEOUT}s. Check Grafana service and port 3000."
+    fi
   done
   echo
-  info "Grafana is ready."
+  info "Grafana API is ready."
 
+  # Use API token for authentication
+  GRAFANA_TOKEN=$(cat /opt/grafana_token 2>/dev/null) || error "Failed to read Grafana API token from /opt/grafana_token."
+
+  # Delete existing datasource
+  info "Deleting existing InfluxDB datasource if it exists..."
+  RESPONSE=$(curl -s -w "%{http_code}" -o /tmp/grafana_response.txt \
+    -H "Authorization: Bearer $GRAFANA_TOKEN" \
+    -X DELETE http://localhost:3000/api/datasources/name/InfluxDB)
+  CODE=$(echo "$RESPONSE" | tail -n1)
+  if [[ "$CODE" =~ 20[0-4] ]]; then
+    info "Existing InfluxDB datasource deleted (HTTP $CODE)."
+  else
+    log "[WARN] Failed to delete existing datasource (HTTP $CODE). Continuing..."
+  fi
+
   # Prepare JSON
   DATA_SOURCE_JSON=$(cat <<EOF
 {
@@ -131,25 +190,25 @@
 EOF
 )
 
-  # Send to Grafana
-  info "Configuring InfluxDB datasource via API..."
+  # Create datasource
+  info "Creating InfluxDB datasource via API..."
   RESPONSE=$(curl -s -w "%{http_code}" -o /tmp/grafana_response.txt \
     -H "Content-Type: application/json" \
-    -H "Authorization: Basic $(echo -n "$GRAFANA_USER:$GRAFANA_PASSWORD" | base64)" \
+    -H "Authorization: Bearer $GRAFANA_TOKEN" \
     -X POST http://localhost:3000/api/datasources \
     -d "$DATA_SOURCE_JSON")
 
-  BODY=$(sed '$d' /tmp/grafana_response.txt)
+  BODY=$(cat /tmp/grafana_response.txt)
   CODE=$(echo "$RESPONSE" | tail -n1)
 
   if [[ "$CODE" =~ 20[01] ]]; then
-    info "InfluxDB datasource configured (HTTP $CODE)."
+    info "InfluxDB datasource created (HTTP $CODE)."
   else
     echo "$BODY" >> "$LOG_FILE"
-    error "Failed to configure datasource (HTTP $CODE). Check $LOG_FILE for details."
+    error "Failed to create datasource (HTTP $CODE). Response: $BODY"
   fi
 
-  # Adding firewall rule for Grafana
+  # Configure firewall
   info "Configuring firewall to allow access to Grafana on port 3000..."
   firewall-cmd --permanent --add-port=3000/tcp >> "$LOG_FILE" 2>&1 || error "Failed to add firewall rule."
   firewall-cmd --reload >> "$LOG_FILE" 2>&1 || error "Failed to reload firewall."
@@ -160,9 +219,10 @@
 # Main
 #---------------------------
 [[ $EUID -ne 0 ]] && error "This script must be run as root."
-for cmd in curl systemctl rpm awk dnf tee firewall-cmd; do command_exists "$cmd" || error "$cmd is required."; done
+for cmd in curl systemctl rpm awk dnf tee firewall-cmd jq; do command_exists "$cmd" || error "$cmd is required."; done
 mkdir -p "$(dirname "$LOG_FILE")"
 install_grafana
 reset_admin_password
+create_api_token
 add_influxdb_datasource
 info "Script completed successfully."
Index: /branches/amp_4_0/platform/tools/install_nginx.sh
===================================================================
--- /branches/amp_4_0/platform/tools/install_nginx.sh	(revision 2627)
+++ /branches/amp_4_0/platform/tools/install_nginx.sh	(working copy)
@@ -1,11 +1,12 @@
 #!/bin/bash
 
 # Script to configure Nginx on Rocky Linux 9.5 as a reverse proxy for:
-# - Custom app (backend at http://127.0.0.1:3000 or static page) on HTTPS (port 443) at root (e.g., /, /login)
+# - Custom app (backend at http://127.0.0.1:3033 or static page) on HTTPS (port 443) at root (e.g., /, /login)
 # - Kibana (backend at http://127.0.0.1:5601) accessible via /visualization on HTTPS (port 443)
+# - Grafana (backend at http://127.0.0.1:3000) accessible via /monitoring on HTTPS (port 443)
 # Uses self-signed certificates and the server's IP address instead of a domain name.
-# Kibana paths are scoped under /visualization/ to avoid conflicts with custom app paths (e.g., /login).
-# Fixes duplicate server.host and handles Kibana redirects to stay under /visualization/.
+# Kibana paths are scoped under /visualization/ and Grafana under /monitoring/ to avoid conflicts with custom app paths (e.g., /login).
+# Fixes duplicate server.host and handles redirects to stay under respective paths.
 
 # --- Variables ---
 INSTALL_LOG_FILE="/var/log/nginx_installation.log"
@@ -17,8 +18,9 @@
 SSL_CRT="${SSL_DIR}/server.crt"
 SSL_COMMON_NAME="${SERVER_IP:-$(ip addr show | grep -oE 'inet [0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | awk '{print $2}' | grep -v '127.0.0.1' | head -1)}"
 SSL_DAYS=365
-BACKEND_URL="http://127.0.0.1:3000" # Backend for custom app
+BACKEND_URL="http://127.0.0.1:3033" # Backend for custom app
 KIBANA_BACKEND_URL="http://127.0.0.1:5601" # Kibana backend
+GRAFANA_BACKEND_URL="http://127.0.0.1:3000" # Grafana backend
 
 # --- Functions ---
 log_info() {
@@ -86,6 +88,7 @@
 
 # --- Check Backend Services ---
 check_service "${KIBANA_BACKEND_URL}" "Kibana"
+check_service "${GRAFANA_BACKEND_URL}" "Grafana"
 if curl -s --connect-timeout 5 "${BACKEND_URL}" &>/dev/null; then
     log_info "Main application is accessible at ${BACKEND_URL}."
 else
@@ -131,8 +134,9 @@
     sudo semanage fcontext -a -t httpd_config_t "${SSL_DIR}(/.*)?" &>> "${INSTALL_LOG_FILE}"
     sudo restorecon -R -v "${SSL_DIR}" &>> "${INSTALL_LOG_FILE}"
     sudo setsebool -P httpd_can_network_connect 1 &>> "${INSTALL_LOG_FILE}"
-    sudo semanage port -a -t http_port_t -p tcp 3000 2>/dev/null || sudo semanage port -m -t http_port_t -p tcp 3000 &>> "${INSTALL_LOG_FILE}"
+    sudo semanage port -a -t http_port_t -p tcp 3033 2>/dev/null || sudo semanage port -m -t http_port_t -p tcp 3033 &>> "${INSTALL_LOG_FILE}"
     sudo semanage port -a -t http_port_t -p tcp 5601 2>/dev/null || sudo semanage port -m -t http_port_t -p tcp 5601 &>> "${INSTALL_LOG_FILE}"
+    sudo semanage port -a -t http_port_t -p tcp 3000 2>/dev/null || sudo semanage port -m -t http_port_t -p tcp 3000 &>> "${INSTALL_LOG_FILE}"
 else
     log_warning "SELinux tools not found. Skipping SELinux configuration. Set SELinux to permissive mode or manually configure."
     log_info "To set SELinux to permissive: sudo setenforce 0"
@@ -183,8 +187,25 @@
     log_error "Kibana configuration file not found at ${KIBANA_CONF}. Ensure Kibana is installed and configured."
 fi
 
+# --- Configure Grafana Base Path ---
+log_info "Configuring Grafana with base path /monitoring..."
+GRAFANA_CONF="/etc/grafana/grafana.ini"
+if [ -f "${GRAFANA_CONF}" ]; then
+    # Update Grafana configuration for base path
+    sudo sed -i 's|^;\?\s*root_url\s*=.*|root_url = https://'${SSL_COMMON_NAME}'/monitoring/|' "${GRAFANA_CONF}" &>> "${INSTALL_LOG_FILE}"
+    sudo sed -i 's|^;\?\s*serve_from_sub_path\s*=.*|serve_from_sub_path = true|' "${GRAFANA_CONF}" &>> "${INSTALL_LOG_FILE}"
+    log_info "Restarting Grafana to apply configuration..."
+    sudo systemctl restart grafana-server &>> "${INSTALL_LOG_FILE}"
+    if [ $? -ne 0 ]; then
+        log_error "Failed to restart Grafana. Check 'sudo systemctl status grafana-server' or ${INSTALL_LOG_FILE}."
+    fi
+    log_info "Grafana configured with base path /monitoring."
+else
+    log_error "Grafana configuration file not found at ${GRAFANA_CONF}. Ensure Grafana is installed and configured."
+fi
+
 # --- Configure Nginx ---
-log_info "Configuring Nginx for custom app and Kibana."
+log_info "Configuring Nginx for custom app, Kibana, and Grafana."
 if [ -f "${NGINX_DEFAULT_CONF}" ]; then
     log_info "Removing default Nginx configuration file: ${NGINX_DEFAULT_CONF}"
     sudo rm "${NGINX_DEFAULT_CONF}" &>> "${INSTALL_LOG_FILE}"
@@ -230,17 +251,30 @@
 
     # Kibana at /visualization/
     location /visualization/ {
-      proxy_pass http://127.0.0.1:5601;  # No trailing slash!
-      proxy_http_version 1.1;
-      proxy_set_header Host \$host;
-      proxy_set_header X-Real-IP \$remote_addr;
-      proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
-      proxy_set_header X-Forwarded-Proto \$scheme;
-      proxy_set_header Upgrade \$http_upgrade;
-      proxy_set_header Connection \"upgrade";
-      proxy_cache_bypass \$http_upgrade;
+        proxy_pass http://127.0.0.1:5601;  # No trailing slash!
+        proxy_http_version 1.1;
+        proxy_set_header Host \$host;
+        proxy_set_header X-Real-IP \$remote_addr;
+        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Proto \$scheme;
+        proxy_set_header Upgrade \$http_upgrade;
+        proxy_set_header Connection "upgrade";
+        proxy_cache_bypass \$http_upgrade;
     }
 
+    # Grafana at /monitoring/
+    location /monitoring/ {
+        proxy_pass http://127.0.0.1:3000;  # No trailing slash!
+        proxy_http_version 1.1;
+        proxy_set_header Host \$host;
+        proxy_set_header X-Real-IP \$remote_addr;
+        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
+        proxy_set_header X-Forwarded-Proto \$scheme;
+        proxy_set_header Upgrade \$http_upgrade;
+        proxy_set_header Connection "upgrade";
+        proxy_cache_bypass \$http_upgrade;
+    }
+
     # Main application
     $(if [ "$USE_STATIC_PAGE" = true ]; then
         echo "location / {
@@ -302,7 +336,7 @@
 fi
 log_info "Nginx service started and enabled successfully."
 
-# --- Verify Kibana Accessibility ---
+# --- Verify Accessibility ---
 log_info "Verifying Kibana accessibility at https://${SSL_COMMON_NAME}/visualization..."
 if ! curl -s --connect-timeout 5 --insecure "https://${SSL_COMMON_NAME}/visualization" &>/dev/null; then
     log_warning "Kibana is not accessible at https://${SSL_COMMON_NAME}/visualization. Checking backend directly..."
@@ -313,22 +347,36 @@
 fi
 log_info "Kibana is accessible at https://${SSL_COMMON_NAME}/visualization."
 
-# --- Verify Kibana and App Path Accessibility ---
-log_info "Verifying path accessibility for Kibana and custom app..."
+log_info "Verifying Grafana accessibility at https://${SSL_COMMON_NAME}/monitoring..."
+if ! curl -s --connect-timeout 5 --insecure "https://${SSL_COMMON_NAME}/monitoring" &>/dev/null; then
+    log_warning "Grafana is not accessible at https://${SSL_COMMON_NAME}/monitoring. Checking backend directly..."
+    if ! curl -s --connect-timeout 5 "${GRAFANA_BACKEND_URL}" &>/dev/null; then
+        log_error "Grafana backend (${GRAFANA_BACKEND_URL}) is not responding. Check 'sudo systemctl status grafana-server' or ${INSTALL_LOG_FILE}."
+    fi
+    log_warning "Grafana backend is responding, but proxying failed. Check Nginx logs: /var/log/nginx/error.log and /var/log/nginx/access.log"
+fi
+log_info "Grafana is accessible at https://${SSL_COMMON_NAME}/monitoring."
+
+# --- Verify Path Accessibility ---
+log_info "Verifying path accessibility for Kibana, Grafana, and custom app..."
 if ! curl -s --connect-timeout 5 --insecure "https://${SSL_COMMON_NAME}/visualization/login" &>/dev/null; then
     log_warning "Kibana login page not accessible at https://${SSL_COMMON_NAME}/visualization/login. Check Kibana status."
 fi
+if ! curl -s --connect-timeout 5 --insecure "https://${SSL_COMMON_NAME}/monitoring/login" &>/dev/null; then
+    log_warning "Grafana login page not accessible at https://${SSL_COMMON_NAME}/monitoring/login. Check Grafana status."
+fi
 if ! curl -s --connect-timeout 5 --insecure "https://${SSL_COMMON_NAME}/login" &>/dev/null; then
     log_warning "Custom app login page not accessible at https://${SSL_COMMON_NAME}/login. Check app backend or Nginx configuration."
 fi
 log_info "Path accessibility check completed."
 
-log_info "Nginx configuration complete. Serving custom app and Kibana on port 443."
+log_info "Nginx configuration complete. Serving custom app, Kibana, and Grafana on port 443."
 log_info "Ensure your firewall allows inbound traffic to ports 80 and 443."
 log_info "************************************************************************************************"
 log_info "** IMPORTANT ACCESS INFORMATION **"
 log_info "************************************************************************************************"
 log_info "- Custom application: https://${SSL_COMMON_NAME} (e.g., /, /login)"
 log_info "- Kibana: https://${SSL_COMMON_NAME}/visualization (e.g., /visualization/login)"
+log_info "- Grafana: https://${SSL_COMMON_NAME}/monitoring (e.g., /monitoring/login)"
 log_warning "Browsers will show security warnings for the self-signed certificate. For production, obtain a trusted certificate from Let's Encrypt: https://letsencrypt.org/"
 log_info "Full installation log: ${INSTALL_LOG_FILE}"
