# How CasaOS Implements Its Health Check Service: Architecture and Code Deep Dive

> Discover how CasaOS implements its health check service by querying systemd and scanning ports. Explore the architecture and code behind this essential feature. Learn more now.

- Repository: [IceWhale/CasaOS](https://github.com/IceWhaleTech/CasaOS)
- Tags: architecture
- Published: 2026-06-28

---

**CasaOS implements its health check service through a dedicated `HealthService` interface that queries systemd for CasaOS service status and scans system ports, exposing the results via REST endpoints at `/api/v2/health/services` and `/api/v2/health/ports`.**

The health check service in the IceWhaleTech/CasaOS repository provides real-time visibility into internal system services and network port utilization. This subsystem combines Go interface design with external utilities from the CasaOS-Common package to deliver both programmatic and HTTP access to critical health metrics. Understanding this implementation reveals how CasaOS monitors its own operational state through clean abstraction layers and standard Linux interfaces.

## Health Service Architecture

The implementation follows a layered architecture consisting of an interface definition, concrete implementation, and HTTP exposure layer.

### The HealthService Interface

The contract for health checks is defined in [`service/health.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/service/health.go) through the `HealthService` interface. This interface declares two primary methods:

- `Services()` – Returns a map categorizing CasaOS services by their running status
- `Ports()` – Returns slices of occupied TCP and UDP ports

This abstraction allows the health subsystem to remain agnostic of specific implementation details while providing a consistent API for the rest of the application.

### Concrete Implementation

The `service` struct in [`service/health.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/service/health.go) provides the concrete implementation of the `HealthService` interface. When instantiated, it leverages two critical utilities from the CasaOS-Common package:

- **`systemctl.ListServices("casaos*")`** – Queries systemd for services matching the CasaOS pattern
- **`port.ListPortsInUse()`** – Enumerates open network ports by scanning `/proc/net/{tcp,udp}` or utilizing `netstat`

The results are packaged into structures required by the interface, specifically splitting service lists into `running` and `notRunning` categories and returning port data as separate integer slices for TCP and UDP.

### Service Registration

The health service is wired into the global dependency container in [`service/service.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/service/service.go). The `NewHealthService()` factory function creates fresh instances, which are then stored in the `Repository` struct under the `health` field. The `Health()` accessor method makes this service available to HTTP handlers and other consumers throughout the application.

## Data Collection Mechanisms

Understanding how CasaOS gathers health data requires examining the interaction between the core service and underlying system utilities.

### Querying Systemd Services

The `(*service).Services()` method invokes `systemctl.ListServices("casaos*")` from the CasaOS-Common utilities. This helper executes a `systemctl` query, parses the output, and returns a slice of structures containing `Name` and `Running` fields. The implementation then partitions these results into two lists keyed by boolean values: `true` for running services and `false` for non-running services.

### Scanning Network Ports

For port enumeration, the `(*service).Ports()` method forwards calls to `port.ListPortsInUse()`. This CasaOS-Common utility examines the system's network tables to identify occupied TCP and UDP ports, returning them as separate integer slices. A minimal test in [`service/health_test.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/service/health_test.go) ensures this functionality returns non-empty slices without errors, validating the helper works across different CI environments.

## HTTP API Exposure

The REST endpoints exposing health data are implemented in [`route/v2/health.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v2/health.go). These handlers interact with the service layer through the global `MyService` repository.

The router registers three primary endpoints:

- **`GET /api/v2/health/services`** – Returns running and stopped CasaOS services via `GetHealthServices`
- **`GET /api/v2/health/ports`** – Returns occupied TCP and UDP ports via `GetHealthPorts`
- **`GET /api/v2/health/logs`** – Provides access to system logs (referenced in the route handlers)

Each handler calls `MyService.Health()` to access the service instance, executes the appropriate method, and marshals the results into OpenAPI-generated response models (`HealthServices` and `HealthPorts`). Errors are translated into `500` JSON payloads, while successful responses return structured data matching the API specification.

## Practical Usage Examples

Developers can interact with the health check service either programmatically through Go or via HTTP requests.

### Consuming the Health Service in Go

To access health data directly from within the CasaOS codebase or external Go packages:

```go
import (
    "github.com/IceWhaleTech/CasaOS/service"
    "log"
)

func main() {
    // Obtain a health service instance
    h := service.NewHealthService()

    // 1️⃣ Get service status
    services, err := h.Services()
    if err != nil {
        log.Fatalf("failed to list services: %v", err)
    }
    log.Printf("Running:   %v", *services[true])
    log.Printf("NotRunning:%v", *services[false])

    // 2️⃣ Get occupied ports
    tcp, udp, err := h.Ports()
    if err != nil {
        log.Fatalf("failed to list ports: %v", err)
    }
    log.Printf("TCP ports: %v", tcp)
    log.Printf("UDP ports: %v", udp)
}

```

This pattern mirrors the internal usage found in the HTTP handlers.

### Accessing Health Endpoints via REST

For external monitoring or debugging, use standard HTTP requests:

```bash

# List running and stopped CasaOS services

curl -s http://localhost:80/api/v2/health/services | jq .

# List occupied ports

curl -s http://localhost:80/api/v2/health/ports | jq .

```

Both endpoints return JSON objects conforming to the OpenAPI definitions (`HealthServices` and `HealthPorts`), making them suitable for integration with monitoring systems and automated health checks.

## Summary

- **CasaOS** exposes health metrics through a dedicated `HealthService` interface defined in [`service/health.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/service/health.go), implementing dependency injection patterns for testability.
- The service queries **systemd** via `systemctl.ListServices("casaos*")` to determine which CasaOS services are running or stopped.
- **Port enumeration** relies on `port.ListPortsInUse()` from CasaOS-Common, scanning `/proc/net/{tcp,udp}` to identify occupied TCP and UDP ports.
- Global registration occurs in [`service/service.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/service/service.go) through `NewHealthService()` and the `MyService` repository, making the health service accessible throughout the application.
- REST endpoints in [`route/v2/health.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v2/health.go) expose `/api/v2/health/services` and `/api/v2/health/ports`, returning OpenAPI-compliant JSON responses suitable for external monitoring tools.

## Frequently Asked Questions

### How does CasaOS determine if its services are running?

CasaOS queries systemd using the `systemctl.ListServices("casaos*")` function from the CasaOS-Common package. This utility executes a `systemctl` command, parses the output to extract service names and their running states, and returns structured data that the `HealthService` implementation partitions into running and non-running categories.

### What network ports does the health check service monitor?

The service monitors all TCP and UDP ports currently in use on the system. The `(*service).Ports()` method calls `port.ListPortsInUse()`, which returns two separate integer slices—one for TCP ports and one for UDP ports—by examining the system's network tables or using `netstat` as a fallback.

### Where is the health check service instantiated in the CasaOS codebase?

The health service is instantiated in [`service/service.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/service/service.go) within the `NewService()` function. This function creates a new `HealthService` via `NewHealthService()` and stores it in the global `MyService` repository, making it accessible through the `Health()` accessor method used by HTTP handlers in [`route/v2/health.go`](https://github.com/IceWhaleTech/CasaOS/blob/main/route/v2/health.go).

### Can I use the health check service programmatically outside of the HTTP API?

Yes, you can import `github.com/IceWhaleTech/CasaOS/service` and call `NewHealthService()` directly to obtain an instance. This allows you to invoke `Services()` and `Ports()` programmatically from other Go packages without routing through HTTP, as demonstrated in the usage examples above.