## Summary Closes #15 When `logging.json: true` (or `DLC_LOGGING_JSON=true`), the logger was unconditionally initialised to console/text format at the top of `LoadConfig()`, so early log lines — most visibly **"Config file loaded"** — were always written as human-readable text regardless of configuration. ## Root cause Classic chicken-and-egg: the format flag lives inside the config that is being loaded. The format-switch block only ran *after* `v.Unmarshal()`, too late for the config-file log. ## Changes ### `pkg/config/config.go` - Add `peekJSONLogging()`: resolves the JSON flag **before** any log is emitted by (1) checking `DLC_LOGGING_JSON` directly via `os.Getenv`, then (2) doing a minimal throwaway Viper pre-read of the config file for the `logging.json` key. This mirrors Viper's own priority order without parsing the full config twice. - Apply the resolved format immediately and emit **"Logging configured"** as the very first log line. - Remove the now-redundant format-switch block that ran after `Unmarshal()`. ### `scripts/start-server.sh`, `test-graceful-shutdown.sh`, `test-opentelemetry.sh` - Replace hardcoded `PROJECT_DIR` path with a dynamic `SCRIPTS_DIR=$(dirname $(realpath ${BASH_SOURCE[0]}))` derivation so scripts work from any worktree or clone location. ## Test plan - [x] `go test ./pkg/...` — all pass - [x] `scripts/test-graceful-shutdown.sh` — all JSON valid, all startup logs present - [x] Manual smoke test: first line is `{"level":"info",...,"message":"Logging configured"}`, every line is valid JSON Reviewed-on: #16 Co-authored-by: Gabriel Radureau <arcodange@gmail.com> Co-committed-by: Gabriel Radureau <arcodange@gmail.com>
164 lines
4.2 KiB
Bash
Executable File
164 lines
4.2 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# dance-lessons-coach Server Start Script
|
|
# This script starts the server in the background and provides control functions
|
|
|
|
# Configuration
|
|
SCRIPTS_DIR=$(dirname "$(realpath "${BASH_SOURCE[0]}")")
|
|
PROJECT_DIR=$(dirname "$SCRIPTS_DIR")
|
|
SERVER_CMD="go run ./cmd/server"
|
|
LOG_FILE="server.log"
|
|
PID_FILE="server.pid"
|
|
|
|
# Change to project directory
|
|
cd "$PROJECT_DIR" || { echo "Failed to change to project directory"; exit 1; }
|
|
|
|
# Function to start the server
|
|
start_server() {
|
|
echo "Starting dance-lessons-coach server..."
|
|
|
|
# Check if server is already running
|
|
if [ -f "$PID_FILE" ]; then
|
|
if ps -p $(cat $PID_FILE) > /dev/null; then
|
|
echo "Server is already running (PID: $(cat $PID_FILE))"
|
|
return 0
|
|
else
|
|
echo "Found stale PID file, cleaning up..."
|
|
rm -f "$PID_FILE"
|
|
fi
|
|
fi
|
|
|
|
# Start server in background with colors disabled for log file
|
|
export DLC_NO_COLOR=1
|
|
echo '' > "$LOG_FILE"
|
|
nohup $SERVER_CMD > "$LOG_FILE" 2>&1 &
|
|
|
|
# Wait a moment for server to start and get the actual server PID
|
|
sleep 2
|
|
|
|
# Get the PID of the process actually listening on port 8080
|
|
ACTUAL_PID=$(lsof -ti :8080 2>/dev/null || echo "")
|
|
|
|
if [ -z "$ACTUAL_PID" ]; then
|
|
echo "Failed to start server - no process listening on port 8080"
|
|
echo "Check log file for errors: $LOG_FILE"
|
|
rm -f "$PID_FILE"
|
|
unset DLC_NO_COLOR
|
|
return 1
|
|
fi
|
|
|
|
echo $ACTUAL_PID > "$PID_FILE"
|
|
unset DLC_NO_COLOR
|
|
|
|
echo "Server started with PID: $(cat $PID_FILE)"
|
|
echo "Log file: $LOG_FILE"
|
|
echo "Server address: http://localhost:8080"
|
|
echo "Server is running successfully"
|
|
}
|
|
|
|
# Function to stop the server
|
|
stop_server() {
|
|
if [ -f "$PID_FILE" ]; then
|
|
echo "Stopping server..."
|
|
kill -TERM $(cat "$PID_FILE") 2>/dev/null
|
|
|
|
# Wait for graceful shutdown
|
|
for i in {1..10}; do
|
|
if ! ps -p $(cat "$PID_FILE") > /dev/null; then
|
|
echo "Server stopped successfully"
|
|
rm -f "$PID_FILE"
|
|
return 0
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
# Force kill if not stopped
|
|
echo "Server did not stop gracefully, forcing kill..."
|
|
kill -9 $(cat "$PID_FILE") 2>/dev/null
|
|
rm -f "$PID_FILE"
|
|
return 1
|
|
else
|
|
echo "No server is running (PID file not found)"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to check server status
|
|
status_server() {
|
|
if [ -f "$PID_FILE" ]; then
|
|
if ps -p $(cat "$PID_FILE") > /dev/null; then
|
|
echo "Server is running (PID: $(cat $PID_FILE))"
|
|
echo "Started: $(ps -p $(cat $PID_FILE) -o lstart=)"
|
|
return 0
|
|
else
|
|
echo "Server PID file exists but process is not running"
|
|
return 1
|
|
fi
|
|
else
|
|
echo "Server is not running"
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Function to show server logs
|
|
tail_logs() {
|
|
if [ -f "$LOG_FILE" ]; then
|
|
echo "=== Server Logs ==="
|
|
tail -n 50 "$LOG_FILE"
|
|
else
|
|
echo "No log file found: $LOG_FILE"
|
|
fi
|
|
}
|
|
|
|
# Function to test API endpoints
|
|
test_api() {
|
|
echo "Testing API endpoints..."
|
|
|
|
# Test health endpoint
|
|
echo "Testing /api/health:"
|
|
curl -s http://localhost:8080/api/health
|
|
echo ""
|
|
|
|
# Test greet endpoint
|
|
echo "Testing /api/v1/greet/:"
|
|
curl -s http://localhost:8080/api/v1/greet/
|
|
echo ""
|
|
|
|
# Test greet with name
|
|
echo "Testing /api/v1/greet/John:"
|
|
curl -s http://localhost:8080/api/v1/greet/John
|
|
echo ""
|
|
}
|
|
|
|
# Main script logic
|
|
case "$1" in
|
|
start)
|
|
start_server
|
|
;;
|
|
stop)
|
|
stop_server
|
|
;;
|
|
restart)
|
|
stop_server
|
|
start_server
|
|
;;
|
|
status)
|
|
status_server
|
|
;;
|
|
logs)
|
|
tail_logs
|
|
;;
|
|
test)
|
|
test_api
|
|
;;
|
|
*)
|
|
echo "Usage: $0 {start|stop|restart|status|logs|test}"
|
|
echo " start - Start the server"
|
|
echo " stop - Stop the server"
|
|
echo " restart - Restart the server"
|
|
echo " status - Check server status"
|
|
echo " logs - Show server logs"
|
|
echo " test - Test API endpoints"
|
|
exit 1
|
|
;;
|
|
esac |