mirror of
https://github.com/pablorevilla-meshtastic/meshview.git
synced 2026-08-06 08:53:20 +02:00
health endpoint
This commit is contained in:
@@ -288,15 +288,46 @@ Request: `/api/lang?section=chat`
|
||||
|
||||
---
|
||||
|
||||
## 9. Version API
|
||||
## 9. Health Check API
|
||||
|
||||
### GET `/health`
|
||||
Health check endpoint for monitoring, load balancers, and orchestration systems.
|
||||
|
||||
**Response Example (Healthy)**
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"timestamp": "2025-11-03T14:30:00.123456Z",
|
||||
"version": "2.0.8",
|
||||
"git_revision": "6416978",
|
||||
"database": "connected"
|
||||
}
|
||||
```
|
||||
|
||||
**Response Example (Unhealthy)**
|
||||
Status Code: `503 Service Unavailable`
|
||||
```json
|
||||
{
|
||||
"status": "unhealthy",
|
||||
"timestamp": "2025-11-03T14:30:00.123456Z",
|
||||
"version": "2.0.8",
|
||||
"git_revision": "6416978",
|
||||
"database": "disconnected"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Version API
|
||||
|
||||
### GET `/version`
|
||||
Returns version information including semver and git revision.
|
||||
Returns detailed version information including semver, release date, and git revision.
|
||||
|
||||
**Response Example**
|
||||
```json
|
||||
{
|
||||
"version": "2.0.8 ~ 10-22-25",
|
||||
"version": "2.0.8",
|
||||
"release_date": "2025-10-22",
|
||||
"git_revision": "6416978a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q",
|
||||
"git_revision_short": "6416978"
|
||||
}
|
||||
|
||||
@@ -9,5 +9,6 @@ These documents are intended for developers, contributors, and advanced users wh
|
||||
- [ALEMBIC_SETUP.md](ALEMBIC_SETUP.md) - Database migration setup and management
|
||||
- [TIMESTAMP_MIGRATION.md](TIMESTAMP_MIGRATION.md) - Details on timestamp schema changes
|
||||
- [API_Documentation.md](API_Documentation.md) - REST API endpoints and usage
|
||||
- [CODE_IMPROVEMENTS.md](CODE_IMPROVEMENTS.md) - Suggested code improvements and refactoring ideas
|
||||
|
||||
For initial setup and basic usage instructions, please see the main [README.md](../README.md) in the root directory.
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
"""Version information for MeshView."""
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
__version__ = "3.0.0"
|
||||
__release_date__ = "2025-11-05"
|
||||
|
||||
|
||||
def get_git_revision():
|
||||
"""Get the current git revision hash."""
|
||||
try:
|
||||
repo_dir = Path(__file__).parent.parent
|
||||
result = subprocess.run(
|
||||
["git", "rev-parse", "HEAD"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
cwd=repo_dir,
|
||||
)
|
||||
return result.stdout.strip()
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
return "unknown"
|
||||
|
||||
|
||||
def get_git_revision_short():
|
||||
"""Get the short git revision hash."""
|
||||
try:
|
||||
repo_dir = Path(__file__).parent.parent
|
||||
result = subprocess.run(
|
||||
["git", "rev-parse", "--short", "HEAD"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
cwd=repo_dir,
|
||||
)
|
||||
return result.stdout.strip()
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
return "unknown"
|
||||
|
||||
|
||||
def get_version_info():
|
||||
"""Get complete version information."""
|
||||
return {
|
||||
"version": __version__,
|
||||
"release_date": __release_date__,
|
||||
"git_revision": get_git_revision(),
|
||||
"git_revision_short": get_git_revision_short(),
|
||||
}
|
||||
|
||||
|
||||
# Cache git info at import time for performance
|
||||
_git_revision = get_git_revision()
|
||||
_git_revision_short = get_git_revision_short()
|
||||
|
||||
# Full version string for display
|
||||
__version_string__ = f"{__version__} ~ {__release_date__}"
|
||||
+35
-30
@@ -19,9 +19,17 @@ from google.protobuf.message import Message
|
||||
from jinja2 import Environment, PackageLoader, Undefined, select_autoescape
|
||||
from markupsafe import Markup
|
||||
from pandas import DataFrame
|
||||
from sqlalchemy import text
|
||||
|
||||
from meshtastic.protobuf.portnums_pb2 import PortNum
|
||||
from meshview import config, database, decode_payload, migrations, models, store
|
||||
from meshview.__version__ import (
|
||||
__version__,
|
||||
__version_string__,
|
||||
_git_revision,
|
||||
_git_revision_short,
|
||||
get_version_info,
|
||||
)
|
||||
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
@@ -31,7 +39,7 @@ logging.basicConfig(
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
SEQ_REGEX = re.compile(r"seq \d+")
|
||||
SOFTWARE_RELEASE = "2.0.8 ~ 10-22-25"
|
||||
SOFTWARE_RELEASE = __version_string__ # Keep for backward compatibility
|
||||
CONFIG = config.CONFIG
|
||||
|
||||
env = Environment(loader=PackageLoader("meshview"), autoescape=select_autoescape())
|
||||
@@ -1751,39 +1759,36 @@ async def api_lang(request):
|
||||
return web.json_response(translations)
|
||||
|
||||
|
||||
@routes.get("/health")
|
||||
async def health_check(request):
|
||||
"""Health check endpoint for monitoring and load balancers."""
|
||||
health_status = {
|
||||
"status": "healthy",
|
||||
"timestamp": datetime.datetime.now(datetime.UTC).isoformat(),
|
||||
"version": __version__,
|
||||
"git_revision": _git_revision_short,
|
||||
}
|
||||
|
||||
# Check database connectivity
|
||||
try:
|
||||
async with database.async_session() as session:
|
||||
await session.execute(text("SELECT 1"))
|
||||
health_status["database"] = "connected"
|
||||
except Exception as e:
|
||||
logger.error(f"Database health check failed: {e}")
|
||||
health_status["database"] = "disconnected"
|
||||
health_status["status"] = "unhealthy"
|
||||
return web.json_response(health_status, status=503)
|
||||
|
||||
return web.json_response(health_status)
|
||||
|
||||
|
||||
@routes.get("/version")
|
||||
async def version_endpoint(request):
|
||||
"""Return version information including semver and git revision."""
|
||||
try:
|
||||
# Get git revision hash
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["git", "rev-parse", "HEAD"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
cwd=os.path.dirname(__file__),
|
||||
)
|
||||
git_revision = result.stdout.strip()
|
||||
|
||||
# Also get short hash
|
||||
result_short = subprocess.run(
|
||||
["git", "rev-parse", "--short", "HEAD"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True,
|
||||
cwd=os.path.dirname(__file__),
|
||||
)
|
||||
git_revision_short = result_short.stdout.strip()
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
git_revision = "unknown"
|
||||
git_revision_short = "unknown"
|
||||
|
||||
return web.json_response({
|
||||
"version": SOFTWARE_RELEASE,
|
||||
"git_revision": git_revision,
|
||||
"git_revision_short": git_revision_short,
|
||||
})
|
||||
version_info = get_version_info()
|
||||
return web.json_response(version_info)
|
||||
except Exception as e:
|
||||
logger.error(f"Error in /version: {e}")
|
||||
return web.json_response({"error": "Failed to fetch version info"}, status=500)
|
||||
|
||||
Reference in New Issue
Block a user