Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
113 changes: 113 additions & 0 deletions FRONTEND_LOGGING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Frontend Logging Guide

## Overview

The frontend application has been configured with comprehensive logging to help with debugging and monitoring.

## Logging Configuration

### 1. Instrumentation Hook

The frontend uses Next.js instrumentation hook to enable server-side logging. This is configured in `frontend/next.config.ts`:

```typescript
experimental: {
instrumentationHook: true,
} as any,
```

### 2. Logging Sources

The following components provide logging:

- **`src/instrumentation.ts`**: OpenTelemetry instrumentation logging
- **`src/app/layout.tsx`**: Server-side layout rendering logs
- **`src/app/page.tsx`**: Client-side page component logs

### 3. Environment Variables

All environment variables are managed through Kubernetes ConfigMaps:

- **Base Configuration** (`kubernetes/base/configmaps/app-config.yaml`): Uses `localhost:8080` for local development
- **Speedscale Overlay** (`kubernetes/overlays/speedscale/frontend-config-patch.yaml`): Uses production domain (edit to set your actual domain)

## Expected Log Messages

When the frontend starts and receives requests, you should see:

1. **Instrumentation logs** (server-side):
```
🔍 Registering OpenTelemetry instrumentation for frontend server...
✅ OpenTelemetry instrumentation registered successfully for frontend server
```

2. **Layout rendering logs** (server-side):
```
🚀 Frontend layout component rendered on server
```

3. **Page component logs** (client-side):
```
🏠 Home page component mounted, auth status: { isAuthenticated: false, isLoading: true }
🔓 User not authenticated, redirecting to login
```

## Troubleshooting

### No Logs Appearing

If you're not seeing any log messages when port forwarding:

1. **Check if instrumentation is enabled**:
```bash
kubectl exec -n banking-app <frontend-pod> -- cat /app/.next/server/instrumentation.js
```

2. **Check pod logs**:
```bash
kubectl logs -n banking-app <frontend-pod> -f
```

3. **Verify environment variables**:
```bash
kubectl exec -n banking-app <frontend-pod> -- env | grep -E "(NODE_ENV|OTEL_)"
```

4. **Test with the provided script**:
```bash
./scripts/test-frontend-logs.sh
```

### Common Issues

1. **Instrumentation not loading**: Ensure `experimental.instrumentationHook: true` is set in `next.config.ts`
2. **Build issues**: The instrumentation file is only loaded in production mode with proper environment variables
3. **Client vs Server logs**: Some logs only appear on the server side, others on the client side

## Testing Logging

Use the provided test script to verify logging is working:

```bash
./scripts/test-frontend-logs.sh
```

## Rebuilding the Frontend

After making changes to the logging configuration, rebuild the frontend:

```bash
# Build the frontend
cd frontend
npm run build

# Rebuild the Docker image
docker build -t ghcr.io/speedscale/microsvc/frontend:latest .

# Redeploy to Kubernetes
kubectl rollout restart deployment/frontend -n banking-app
```

## Monitoring

The frontend sends OpenTelemetry traces to Jaeger for monitoring. You can access the Jaeger UI to view traces and spans from the frontend application.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@ docker-compose up -d
./mvnw spring-boot:run
```

### Kubernetes Deployment

**Local Development**:
```bash
# Deploy with localhost configuration
kubectl apply -k kubernetes/base/
```

**Production Deployment**:
```bash
# Deploy with production configuration
kubectl apply -k kubernetes/overlays/speedscale/
```

**Note**: For production, edit `kubernetes/overlays/speedscale/frontend-config-patch.yaml` to set your actual API domain instead of `https://your-api-domain.com`.

### Frontend Development
```bash
# Start Next.js development server
Expand Down
5 changes: 4 additions & 1 deletion frontend/next.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ const nextConfig: NextConfig = {
images: {
unoptimized: true,
},
experimental: {
instrumentationHook: true,
} as any,
async rewrites() {
return [
{
source: '/api/:path*',
destination: `${process.env.BACKEND_API_URL || 'http://api-gateway:8080'}/api/:path*`,
destination: `${process.env.BACKEND_API_URL || 'http://api-gateway:80'}/api/:path*`,
},
]
},
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ export default function RootLayout({
}: Readonly<{
children: React.ReactNode;
}>) {
// Server-side logging for debugging
if (typeof window === 'undefined') {
console.log('🚀 Frontend layout component rendered on server');
}

return (
<html lang='en'>
<body
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ export default function Home() {
const router = useRouter();

useEffect(() => {
console.log('🏠 Home page component mounted, auth status:', { isAuthenticated, isLoading });

if (!isLoading) {
if (isAuthenticated) {
console.log('🔐 User authenticated, redirecting to dashboard');
router.push('/dashboard');
} else {
console.log('🔓 User not authenticated, redirecting to login');
router.push('/login');
}
}
Expand Down
1 change: 1 addition & 0 deletions frontend/src/lib/api/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import axios from 'axios';
import { LoginRequest, RegisterRequest, AuthResponse, User } from '../types/auth';
import { TokenManager } from '../auth/token';

// Use relative URL if NEXT_PUBLIC_API_URL is not set (works with Next.js API proxying)
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || '';
const API_TIMEOUT = parseInt(process.env.NEXT_PUBLIC_API_TIMEOUT || '30000');

Expand Down
1 change: 1 addition & 0 deletions frontend/src/lib/api/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { TokenManager } from '../auth/token';

// Use relative URL if NEXT_PUBLIC_API_URL is not set (works with Next.js API proxying)
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || '';
const API_TIMEOUT = parseInt(process.env.NEXT_PUBLIC_API_TIMEOUT || '30000');

Expand Down
12 changes: 11 additions & 1 deletion kubernetes/base/configmaps/app-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ metadata:
app.kubernetes.io/component: config
app.kubernetes.io/service: frontend
data:
# Backend API configuration
BACKEND_API_URL: "http://api-gateway:80"
NEXT_PUBLIC_API_URL: "http://localhost:8080"

# OpenTelemetry configuration
OTEL_SERVICE_NAME: "frontend"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://jaeger:4318/v1/traces"
OTEL_RESOURCE_ATTRIBUTES: "service.namespace=banking-app"
OTEL_EXPORTER_OTLP_PROTOCOL: "http/protobuf"
OTEL_RESOURCE_ATTRIBUTES: "service.namespace=banking-app"

# Next.js configuration
NODE_ENV: "production"
NEXT_TELEMETRY_DISABLED: "1"
16 changes: 3 additions & 13 deletions kubernetes/base/deployments/frontend-deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,19 +31,9 @@ spec:
ports:
- containerPort: 3000
name: http
env:
- name: BACKEND_API_URL
value: "http://api-gateway:80"
- name: NEXT_PUBLIC_API_URL
value: "http://138.197.228.77"
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: "http://jaeger:4318/v1/traces"
- name: OTEL_EXPORTER_OTLP_PROTOCOL
value: "http/protobuf"
- name: OTEL_SERVICE_NAME
value: "frontend"
- name: OTEL_RESOURCE_ATTRIBUTES
value: "service.namespace=banking-app"
envFrom:
- configMapRef:
name: frontend-config
resources:
requests:
memory: "256Mi"
Expand Down
19 changes: 19 additions & 0 deletions kubernetes/overlays/speedscale/frontend-config-patch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: frontend-config
namespace: banking-app
data:
# Backend API configuration for speedscale deployment
BACKEND_API_URL: "http://api-gateway:80"
NEXT_PUBLIC_API_URL: "https://your-api-domain.com"

# OpenTelemetry configuration
OTEL_SERVICE_NAME: "frontend"
OTEL_EXPORTER_OTLP_ENDPOINT: "http://jaeger:4318/v1/traces"
OTEL_EXPORTER_OTLP_PROTOCOL: "http/protobuf"
OTEL_RESOURCE_ATTRIBUTES: "service.namespace=banking-app"

# Next.js configuration
NODE_ENV: "production"
NEXT_TELEMETRY_DISABLED: "1"
1 change: 1 addition & 0 deletions kubernetes/overlays/speedscale/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ kind: Kustomization

resources:
- ../../base
- frontend-config-patch.yaml

patchesStrategicMerge:
- user-service-annotations.yaml
Expand Down
99 changes: 99 additions & 0 deletions scripts/test-frontend-logs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/bin/bash

# Script to test frontend logging
# This script helps debug frontend logging issues by port forwarding and making test requests

set -e

echo "🔍 Testing Frontend Logging"
echo "=========================="

# Check if kubectl is available
if ! command -v kubectl &> /dev/null; then
echo "❌ kubectl is not installed or not in PATH"
exit 1
fi

# Check if the frontend pod exists
echo "📋 Checking frontend pod status..."
if ! kubectl get pods -n banking-app -l app=frontend | grep -q "Running"; then
echo "❌ Frontend pod is not running. Please ensure the application is deployed."
echo " Run: kubectl get pods -n banking-app"
exit 1
fi

echo "✅ Frontend pod is running"

# Check if the frontend ConfigMap exists
echo "📋 Checking frontend ConfigMap..."
if ! kubectl get configmap frontend-config -n banking-app &> /dev/null; then
echo "❌ Frontend ConfigMap not found. Please ensure the ConfigMap is applied."
echo " Run: kubectl apply -f kubernetes/base/configmaps/app-config.yaml"
exit 1
fi

echo "✅ Frontend ConfigMap exists"

# Display ConfigMap contents for debugging
echo "📄 Frontend ConfigMap contents:"
kubectl get configmap frontend-config -n banking-app -o yaml | grep -A 20 "data:"

# Get the frontend pod name
FRONTEND_POD=$(kubectl get pods -n banking-app -l app=frontend -o jsonpath='{.items[0].metadata.name}')
echo "🎯 Using frontend pod: $FRONTEND_POD"

echo ""
echo "🚀 Starting port forward to frontend pod..."
echo " Local port: 3000"
echo " Pod port: 3000"
echo " Press Ctrl+C to stop port forwarding"
echo ""

# Function to cleanup port forward on exit
cleanup() {
echo ""
echo "🛑 Stopping port forward..."
kill $PORT_FORWARD_PID 2>/dev/null || true
exit 0
}

# Set up trap to cleanup on script exit
trap cleanup EXIT INT TERM

# Start port forward in background
kubectl port-forward -n banking-app $FRONTEND_POD 3000:3000 &
PORT_FORWARD_PID=$!

# Wait a moment for port forward to establish
sleep 3

echo "✅ Port forward established"
echo ""
echo "📝 Now you can:"
echo " 1. Check logs in another terminal: kubectl logs -n banking-app $FRONTEND_POD -f"
echo " 2. Access the frontend at: http://localhost:3000"
echo " 3. Make requests to trigger logging"
echo ""

# Verify environment variables are set in the pod
echo "🔍 Verifying environment variables in pod..."
kubectl exec -n banking-app $FRONTEND_POD -- env | grep -E "(NODE_ENV|OTEL_SERVICE_NAME|BACKEND_API_URL)" || echo "⚠️ Some environment variables not found"

echo ""
echo "🔍 Making test request to trigger logging..."

# Make a test request to trigger logging
if command -v curl &> /dev/null; then
echo "📡 Making test request to http://localhost:3000..."
curl -s -o /dev/null -w "HTTP Status: %{http_code}\n" http://localhost:3000 || echo "⚠️ Request failed (this might be expected if the app is still starting)"
else
echo "⚠️ curl not available, skipping test request"
fi

echo ""
echo "⏳ Waiting for port forward (press Ctrl+C to stop)..."
echo " Check the logs in another terminal with:"
echo " kubectl logs -n banking-app $FRONTEND_POD -f"

# Wait for port forward to continue running
wait $PORT_FORWARD_PID