navi/backend/services/navi_offroute/app.py
Matt 6b8bf15c36 navi-offroute: enable INFO logging for per-stage timing
PR #34 added per-stage Auto timing logs (single-mode probing took..., hybrid
candidate gathering..., hybrid probing took...) at logger.info level, but
navi-offroute has no logging config, so Python's last-resort handler dropped
everything below WARNING and the lines never reached stderr/journal.

This one-line logging.basicConfig(level=logging.INFO) in app.py opens the gate so
those lines surface in journald, letting us localize the 6-7s baseline Auto
latency on in-town routes. No other changes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 02:43:46 +00:00

81 lines
2.6 KiB
Python

"""navi-offroute Flask application factory + gunicorn entry.
Gunicorn entry:
gunicorn 'services.navi_offroute.app:create_app()' --bind 127.0.0.1:8428 --workers 2
"""
import logging
import time
from flask import Flask
from shared.git_sha import git_short_sha
from . import offroute_route, admin
from .mvum import MVUMSpatialIndex
from .mvum_transitions import load_trailheads
from .mvum_parking import load_parking_index
# Emit INFO+ so PR #34 per-stage Auto timing logs (single-mode probing took...,
# hybrid candidate gathering..., hybrid probing took...) reach stderr/journal;
# navi-offroute had no logging config, so the last-resort handler dropped INFO.
logging.basicConfig(level=logging.INFO)
# Process-wide singleton: build the MVUM spatial index once per process (per gunicorn
# worker in prod; once across create_app() calls in tests), not once per app instance.
_MVUM_INDEX = None
def _get_mvum_index():
global _MVUM_INDEX
if _MVUM_INDEX is None:
_MVUM_INDEX = MVUMSpatialIndex()
return _MVUM_INDEX
def create_app():
app = Flask(__name__)
app.config['VERSION'] = git_short_sha()
app.config['METRICS'] = {
'start_time': time.time(),
'request_count': 0,
'last_error_at': None,
}
@app.before_request
def _count_request():
app.config['METRICS']['request_count'] += 1
@app.after_request
def _track_errors(response):
if response.status_code >= 500:
app.config['METRICS']['last_error_at'] = time.strftime(
'%Y-%m-%dT%H:%M:%SZ', time.gmtime()
)
return response
# Load the MVUM spatial index once at service init (logs its own load line).
try:
app.config['MVUM_SPATIAL_INDEX'] = _get_mvum_index()
except Exception as e:
app.logger.warning("MVUM spatial index failed to load: %s", e)
app.config['MVUM_SPATIAL_INDEX'] = None
# Layer 3a: trailhead transition index (process-wide singleton, logs its own line).
try:
app.config['MVUM_TRAILHEAD_INDEX'] = load_trailheads()
except Exception as e:
app.logger.warning("MVUM trailhead index failed to load: %s", e)
app.config['MVUM_TRAILHEAD_INDEX'] = None
# Layer 3b: OSM parking index (process-wide singleton, logs its own line).
try:
app.config['OSM_PARKING_INDEX'] = load_parking_index()
except Exception as e:
app.logger.warning("OSM parking index failed to load: %s", e)
app.config['OSM_PARKING_INDEX'] = None
app.register_blueprint(offroute_route.bp)
app.register_blueprint(admin.bp)
return app