DevPulse is a DevOps logbook for collecting deployment logs, system alerts, and troubleshooting notes. The goal is to help a team quickly understand what happened during a failed deployment or incident by showing the raw information together with AI-generated summaries and suggested fixes.
-
Client:
client/- Dashboard UI for developers and operators.
- Shows logs, alerts, notes, and AI-generated insights.
-
Server microservices:
services/spring-*- Java 21 / Spring Boot 3 services.
- The server side is split into at least three microservices with separate responsibilities.
- Exposes REST APIs and coordinates persistent storage and GenAI analysis.
-
GenAI:
services/py-intelligence/- Separate Python service.
- Produces summaries, troubleshooting hints, and possible next steps from log content.
-
Infrastructure:
infra/- Place for Docker Compose, Kubernetes or Helm files, database setup, Prometheus, and Grafana.
repo/
├── api/ # Single source of truth
│ ├── openapi.yaml # Versioned spec (v1, v2...)
│ └── scripts/ # Helper scripts for code generation
├── services/
│ ├── spring-ingestion/ # Spring Boot service for receiving logs/events
│ ├── spring-logbook/ # Spring Boot service for stored logs and notes
│ ├── spring-alerts/ # Spring Boot service for alerts/incident state
│ └── py-intelligence/ # Python GenAI service
├── client/ # Client component
├── infra/ # Docker Compose, Kubernetes, database, monitoring
└── .github/workflows/ # CI pipelines
client sends requests to the Spring Boot backend services. The backend services manage logs, notes, alerts, and persistent storage. When AI analysis is needed, the backend calls py-intelligence through a defined JSON/HTTP interface. The OpenAPI file in api/ is the shared API contract.
Use this format for feature and bugfix branches:
(feat|fix)/(issue_id)/(name_of_issue)
Examples:
feat/12/add-log-ingestion
fix/18/handle-empty-ai-response
To run this project locally, you must have the following installed:
- Docker (Docker Desktop recommended for Mac/Windows)
- Docker Compose
(Note: You do not need Java, Python, or Node.js installed on your host machine to run the application, as everything runs inside the containers!)
cd infra
docker-compose up --buildRun all commands from the repository root unless noted otherwise.
cd services/spring-alerts
./gradlew :app:clean :app:test :app:build
./gradlew :app:bootRuncd services/spring-ingestion
./gradlew :app:clean :app:test :app:build
./gradlew :app:bootRuncd services/spring-logbook
./gradlew :app:clean :app:test :app:build
./gradlew :app:bootRuncd client
npm ci
npm run lint
npm run test -- --run
npm run build
npm run devUse these for non-watch runs in CI:
# Spring services (run per service directory)
./gradlew :app:test
# Client
npm run test -- --runThe application is configured to run on a Kubernetes cluster (specifically, the AET Rancher cluster) inside the devpulse-prod namespace.
We use GitHub Actions to automate the entire testing, building, and deployment process:
- Pull Requests & Non-Main Branches: The pipeline runs automated unit/integration tests for the Spring Boot microservices, Python intelligence service, and React frontend.
- Main Branch: Once merged into
main, the pipeline:- Builds Docker images for all services.
- Pushes them to the GitHub Container Registry (GHCR) tagged with the unique Git commit SHA.
- Uses
kustomizeto update the Kubernetes manifests with the new image tags. - Deploys the updated manifests directly to the cluster.
For the CD deployment pipeline to succeed, you must add the following Repository Secrets under Settings > Secrets and variables > Actions in GitHub:
KUBE_CONFIG_DATA: The raw text content of yourkubeconfigfile (granting namespace-level access to the cluster).POSTGRES_USER,POSTGRES_PASSWORD, andPOSTGRES_DB: Database credentials.RABBITMQ_USERandRABBITMQ_PASSWORD: Broker credentials.MONGODB_URI: URI to the MongoDB instance used by the alert service.GOOGLE_API_KEY: API key for GenAI analysis features.
Note: The pipeline automatically Base64-encodes these values at runtime, so paste them as raw plain-text in GitHub.
If you have kubectl configured and connected to the cluster, you can perform tasks manually:
Deploy the entire stack with a single command from the project root:
kubectl apply -k infra/k8s/Verify that all pods, services, and workloads are running correctly:
kubectl get all -n devpulse-prod- Via URL: https://team-setops.stud.k8s.aet.cit.tum.de/ is routed through the shared student cluster's ingress-nginx controller.
- Via Gateway NodePort: The gateway service is exposed externally on a dynamically assigned port on every cluster node. To find the port, run:
Look for the port mapped to
kubectl get service gateway -n devpulse-prod
80:under thePORT(S)column (e.g.80:31234/TCP). You can then access the app athttp://<node-ip-address>:<assigned-nodeport>. - Via Local Port-Forwarding: If you are behind a firewall or want to test locally:
Then open http://localhost:8080 in your browser.
kubectl port-forward service/gateway 8080:80 -n devpulse-prod
Interactive API documentation (Swagger UI) is automatically generated and accessible at runtime for each microservice. When running the services locally, you can view the API references at the following URLs:
- Py-Intelligence (FastAPI): http://localhost:8001/docs
- Spring Ingestion:
http://localhost:<PORT>/swagger-ui.html - Spring Alerts:
http://localhost:<PORT>/swagger-ui.html - Spring Logbook:
http://localhost:<PORT>/swagger-ui.html
(Note: Replace <PORT> with the respective mapped ports defined in your docker-compose or Spring application properties).