CoSky Dashboard: Complete Guide to Service Management and Monitoring
The CoSky Dashboard is a React-based web interface that provides real-time service monitoring, interactive topology visualization, and full CRUD operations for configurations, namespaces, and user roles in a CoSky cluster.
The CoSky Dashboard serves as the primary operational interface for the ahoo-wang/cosky service governance platform. This single-page application combines a Spring Boot backend with a modern React frontend to deliver comprehensive insights into your microservices architecture. Operators can monitor service health, explore dependency graphs, and manage governance artifacts through an intuitive web UI deployed alongside the CoSky server.
Getting Started with the CoSky Dashboard
Deploying the dashboard requires only a running CoSky server instance. The UI is automatically packaged within the server distribution and served as static content.
Deploy via Docker
The fastest way to access the CoSky Dashboard is using the official Docker image. Ensure you have a Redis instance available for persistence:
docker run -d --name cosky -p 8080:8080 \
-e SPRING_DATA_REDIS_URL=redis://your-redis-host:6379 \
ahoowang/cosky:latest
Once the container starts, open http://localhost:8080 in your browser. The server logs will display default super-user credentials on first run. After authentication, you can immediately begin managing namespaces, browsing service statistics, and exploring the interactive topology graph.
Architecture and Backend Routing
The dashboard architecture separates concerns between a lightweight Spring Boot controller and a React SPA (Single Page Application) built with Vite.
Spring Boot Controller Implementation
In cosky-rest-api/src/main/kotlin/me/ahoo/cosky/rest/dashboard/DashboardConfiguration.kt, the DashboardConfiguration class handles all UI routing. The controller serves the pre-compiled index.html for all valid routes while maintaining backward compatibility with legacy URLs:
@GetMapping(
"/", HOME_ROUTE, CONFIG_ROUTE, SERVICE_ROUTE,
NAMESPACE_ROUTE, USER_ROUTE, ROLE_ROUTE,
AUDIT_LOG_ROUTE, LOGIN_ROUTE
)
fun home(): ResponseEntity<Resource> = ResponseEntity.ok()
.contentType(MediaType.TEXT_HTML)
.body(indexResource)
@GetMapping(RequestPathPrefix.DASHBOARD, "${RequestPathPrefix.DASHBOARD}**")
fun dashboard(): ResponseEntity<Void> = ResponseEntity.status(HttpStatus.MOVED_PERMANENTLY)
.location(URI.create(HOME_ROUTE))
.build()
The home() method returns the same index.html resource for all client-side routes, enabling the React Router to handle navigation. The dashboard() method implements a permanent redirect (HTTP 301) from legacy /dashboard/** paths to the modern /home route. Static assets are served from dashboard/dist via Spring Boot's static-locations configuration defined in application.yaml.
Frontend Implementation and Service Visualization
The frontend is a TypeScript React application using Ant Design for UI components and XYFlow for graph visualization. Data fetching occurs through the @ahoo-wang/fetcher library with auto-generated API clients.
Real-Time Statistics Dashboard
The main dashboard view is implemented in dashboard/src/pages/dashboard/DashboardPage.tsx. This component fetches cluster statistics using the statApiClient and renders them as Ant Design Statistic cards:
export function DashboardPage() {
const {currentNamespace} = useCurrentNamespaceContext();
const {result: stat = defaultStat} = useQuery<string, GetStatResponse>({
query: currentNamespace,
execute: (ns, _, abort) => statApiClient.getStat(ns, {abortController: abort}),
});
// Renders cards for namespaces, configs, services, and instances
}
The useCurrentNamespaceContext hook manages the namespace selector state from the UI header, while useQuery handles the asynchronous call to statApiClient.getStat(). This endpoint returns aggregated metrics including total services, healthy instances, and configuration counts.
Interactive Service Topology
Service dependencies are visualized in dashboard/src/components/topology/Topology.tsx using the XYFlow (@xyflow/react) library. The component transforms the topology data into interactive nodes and edges:
const {result = {}, loading} = useQuery<string, Record<string, string[]>>({
query: currentNamespace,
execute: (_, __, abort) => statApiClient.getTopology(namespace, {abortController: abort}),
});
const {nodes, edges} = useMemo(() => {
// Maps API data to React Flow nodes/edges with search highlighting
}, [internalNodes, baseEdges, searchTerm, highlightedNodes]);
The getTopology method returns a Map<string, string[]> representing service-to-dependency relationships. The component supports searching for specific services, dimming non-matching nodes, and clicking nodes to highlight connected dependencies in the graph.
Programmatic API Integration
While the CoSky Dashboard provides a rich UI, you can also interact with the underlying REST API directly for automation or custom integrations.
Fetching Statistics via cURL
Retrieve cluster statistics for a specific namespace using the REST endpoint:
curl -s http://localhost:8080/api/v3/stat/cosky | jq .
Example response:
{
"namespaces": 1,
"configs": 12,
"services": { "total": 34, "health": 30 },
"instances": 85
}
Using the TypeScript Client
For dashboard extensions or external TypeScript applications, use the generated statApiClient from dashboard/src/services/clients.ts:
import {statApiClient} from './generated';
async function fetchStat(ns: string) {
const response = await statApiClient.getStat(ns);
console.log('Stat for', ns, response);
}
fetchStat('cosky');
Creating Configurations via REST
Add new configuration files programmatically using a POST request:
curl -X POST http://localhost:8080/api/v3/config \
-H "Content-Type: application/json" \
-d '{
"namespace": "cosky",
"configId": "my-app.yaml",
"content": "server.port: 8081\nlogging.level.root: INFO"
}' | jq .
Summary
The CoSky Dashboard provides a complete operational interface for service governance by combining:
- Spring Boot static resource serving (
DashboardConfiguration.kt) to deliver the React application - Client-side routing handling all paths (
/home,/service,/config, etc.) through a singleindex.htmlentry point - Real-time statistics via
statApiClient.getStat()calls inDashboardPage.tsx - Interactive topology visualization using XYFlow in
Topology.tsxto explore service dependencies - Legacy URL redirects maintaining backward compatibility for existing bookmarks
Frequently Asked Questions
How do I access the CoSky Dashboard after starting the server?
Open a web browser and navigate to http://<host>:<port>/ where your CoSky server is running. If using the default Docker deployment on localhost, this is http://localhost:8080. The dashboard loads automatically from the packaged static files in dashboard/dist.
What technologies power the CoSky Dashboard frontend?
The frontend is built with React and TypeScript, bundled using Vite. It uses Ant Design for the user interface components and XYFlow (@xyflow/react) for rendering the interactive service topology graph. API communication is handled by the @ahoo-wang/fetcher library with generated clients.
Can I use the CoSky Dashboard without the UI for automation?
Yes. The dashboard is a consumer of the cosky-rest-api module. You can call the same endpoints directly, such as GET /api/v3/stat/{namespace} for statistics or GET /api/v3/stat/topology/{namespace} for dependency graphs. The TypeScript client code in dashboard/src/services/clients.ts demonstrates the exact API signatures.
Where are the dashboard static files located in the repository?
The source files reside in the dashboard/ directory at the repository root. The compiled production build is output to dashboard/dist, which is then packaged into the Spring Boot JAR and served via static-locations configuration as defined in cosky-rest-api/src/main/resources/application.yaml.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →