mirror of
https://github.com/wahyd4/links.git
synced 2026-08-08 21:04:53 +10:00
fix(routermon): fix receiver startup, logging config, and JS template escaping
- Remove SO_REUSEADDR from UDP socket so only one gunicorn worker binds
port 5514 (second worker intentionally gets EADDRINUSE and skips)
- Add print() fallback for bind confirmation/errors so startup is visible
even when Django logging config is not fully set up
- Fix duplicate LOGGING dict in settings.py: second assignment was
overriding the first and removing the root logger handler, silently
swallowing all routermon/core startup logs
- Add sys.stderr fallback in core/apps.py ready() for startup exceptions
- Fix JS SyntaxError: {{ top_domains_json }} needs |safe filter since
Django auto-escapes quotes to " inside script tags
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -89,4 +89,6 @@ class CoreConfig(AppConfig):
|
||||
)
|
||||
logger.info("routermon: scheduled cleanup job (every 6h)")
|
||||
except Exception as exc:
|
||||
import sys
|
||||
print(f'routermon: startup error (non-fatal): {exc}', file=sys.stderr, flush=True)
|
||||
logger.warning("routermon: startup error (non-fatal): %s", exc)
|
||||
|
||||
+4
-17
@@ -232,21 +232,8 @@ CRAWL4AI_ENABLED = os.environ.get('CRAWL4AI_ENABLED', 'True').lower() in ('true'
|
||||
BUILD_TIME = os.environ.get('BUILD_TIME', '')
|
||||
BUILD_VERSION = os.environ.get('BUILD_VERSION', '')
|
||||
|
||||
# For debugging
|
||||
LOGGING = {
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'handlers': {
|
||||
'console': {
|
||||
'class': 'logging.StreamHandler',
|
||||
'level': 'DEBUG',
|
||||
},
|
||||
},
|
||||
'loggers': {
|
||||
'links': {
|
||||
'handlers': ['console'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': True,
|
||||
},
|
||||
},
|
||||
LOGGING['loggers']['links'] = {
|
||||
'handlers': ['console'],
|
||||
'level': 'DEBUG',
|
||||
'propagate': False,
|
||||
}
|
||||
|
||||
@@ -54,15 +54,19 @@ def start_receiver(port: int):
|
||||
|
||||
try:
|
||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
# No SO_REUSEADDR: we intentionally want only one worker to bind.
|
||||
# Other workers receive EADDRINUSE and skip cleanly.
|
||||
sock.bind(('0.0.0.0', port))
|
||||
sock.settimeout(1.0)
|
||||
_sock = sock
|
||||
print(f'routermon: UDP syslog receiver bound on port {port}', flush=True)
|
||||
logger.info('routermon: UDP syslog receiver bound on port %d', port)
|
||||
except OSError as exc:
|
||||
if exc.errno == errno.EADDRINUSE:
|
||||
logger.debug('routermon: port %d already bound (another worker), skipping', port)
|
||||
else:
|
||||
import sys
|
||||
print(f'routermon: failed to bind UDP port {port}: {exc}', file=sys.stderr, flush=True)
|
||||
logger.error('routermon: failed to bind UDP port %d: %s', port, exc)
|
||||
return
|
||||
|
||||
|
||||
@@ -324,7 +324,7 @@ async function loadChart() {
|
||||
});
|
||||
|
||||
// Top domains mini bar chart
|
||||
const topData = {{ top_domains_json }};
|
||||
const topData = {{ top_domains_json|safe }};
|
||||
const top10 = topData.slice(0, 10).reverse();
|
||||
domainsChartEl.setOption({
|
||||
tooltip: {trigger: 'axis', axisPointer: {type: 'shadow'}},
|
||||
|
||||
Reference in New Issue
Block a user