数据源容错: 单源失败不中断+页面告警; 记录source_status
This commit is contained in:
+12
@@ -45,6 +45,8 @@
|
|||||||
.dod-hi-pos{background:var(--rose-50);color:var(--success);font-weight:600;}
|
.dod-hi-pos{background:var(--rose-50);color:var(--success);font-weight:600;}
|
||||||
.dod-hi-neg{background:var(--rose-100);color:var(--danger);font-weight:600;}
|
.dod-hi-neg{background:var(--rose-100);color:var(--danger);font-weight:600;}
|
||||||
.sub-note{color:var(--ink-60);font-size:12px;margin:4px 2px 10px;}
|
.sub-note{color:var(--ink-60);font-size:12px;margin:4px 2px 10px;}
|
||||||
|
.src-alert{background:#FBF0E4;border:1px solid var(--warning);color:#8a5a1f;border-radius:8px;padding:10px 14px;margin-bottom:14px;font-size:13px;font-weight:500;}
|
||||||
|
.src-alert b{color:var(--warning);}
|
||||||
.total-row td{font-weight:700;background:var(--rose-50);}
|
.total-row td{font-weight:700;background:var(--rose-50);}
|
||||||
.ctrl{display:flex;gap:14px;align-items:center;flex-wrap:wrap;margin-bottom:10px;}
|
.ctrl{display:flex;gap:14px;align-items:center;flex-wrap:wrap;margin-bottom:10px;}
|
||||||
.ctrl label{font-size:13px;cursor:pointer;user-select:none;color:var(--ink-80);}
|
.ctrl label{font-size:13px;cursor:pointer;user-select:none;color:var(--ink-80);}
|
||||||
@@ -63,6 +65,7 @@
|
|||||||
<div class="logo"><span class="roas">roas</span><span class="bloom">bl</span><span class="ring"></span><span class="bloom">m</span></div>
|
<div class="logo"><span class="roas">roas</span><span class="bloom">bl</span><span class="ring"></span><span class="bloom">m</span></div>
|
||||||
<h1>DSP Daily 日报</h1>
|
<h1>DSP Daily 日报</h1>
|
||||||
<div class="meta" id="meta">加载中…</div>
|
<div class="meta" id="meta">加载中…</div>
|
||||||
|
<div id="srcAlert" class="src-alert hide"></div>
|
||||||
<div class="tabs">
|
<div class="tabs">
|
||||||
<div class="tab active" data-tab="overview">总日报</div>
|
<div class="tab active" data-tab="overview">总日报</div>
|
||||||
<div class="tab" data-tab="cust">客户分类</div>
|
<div class="tab" data-tab="cust">客户分类</div>
|
||||||
@@ -488,6 +491,15 @@ document.addEventListener('input',function(e){
|
|||||||
fetch('data.json?_='+Date.now()).then(function(r){return r.json();}).then(function(d){
|
fetch('data.json?_='+Date.now()).then(function(r){return r.json();}).then(function(d){
|
||||||
D=d;
|
D=d;
|
||||||
document.getElementById('meta').textContent='数据更新时间:'+(d.updated_at||'—')+' | Overall '+(d.overall||[]).length+' 天';
|
document.getElementById('meta').textContent='数据更新时间:'+(d.updated_at||'—')+' | Overall '+(d.overall||[]).length+' 天';
|
||||||
|
// 数据源状态告警
|
||||||
|
(function(){
|
||||||
|
var ss=d.source_status||{}; var msgs=[];
|
||||||
|
if(ss.report && String(ss.report).indexOf('fail')===0) msgs.push('MS 数据源(report/v2/list)凭证失效 —— MS 表与带 _API 的 account 数据未更新,请更新 MS token');
|
||||||
|
if(ss.superset && String(ss.superset).indexOf('fail')===0) msgs.push('Superset 数据源凭证失效 —— Midas 表与无 _API 的 account 数据未更新,请更新 Superset cookie');
|
||||||
|
var el=document.getElementById('srcAlert');
|
||||||
|
if(msgs.length){ el.innerHTML='<b>⚠ 数据源告警:</b>'+msgs.join(';')+'。'; el.classList.remove('hide'); }
|
||||||
|
else { el.classList.add('hide'); }
|
||||||
|
})();
|
||||||
renderOverall();
|
renderOverall();
|
||||||
renderAccTable('tCN', d.cn, 'DSP CN revenue');
|
renderAccTable('tCN', d.cn, 'DSP CN revenue');
|
||||||
renderAccTable('tIntl', d.international, 'DSP international');
|
renderAccTable('tIntl', d.international, 'DSP international');
|
||||||
|
|||||||
@@ -171,8 +171,30 @@ def fetch_report(ymd):
|
|||||||
d=json.load(urllib.request.urlopen(req,timeout=180,context=ctx))
|
d=json.load(urllib.request.urlopen(req,timeout=180,context=ctx))
|
||||||
return d['data']['list']
|
return d['data']['list']
|
||||||
|
|
||||||
|
# ---- 各源独立容错:一个失败不影响另一个 ----
|
||||||
|
src_status={'superset':'ok','report':'ok'}
|
||||||
|
sup=[]; rep=[]
|
||||||
|
try:
|
||||||
print('[fetch] Superset...'); sup=fetch_superset()
|
print('[fetch] Superset...'); sup=fetch_superset()
|
||||||
|
except Exception as e:
|
||||||
|
src_status['superset']='fail: '+str(e)[:120]
|
||||||
|
print('[ERROR] Superset 拉取失败:', str(e)[:200])
|
||||||
|
try:
|
||||||
print('[fetch] report/v2/list T-1...'); rep=fetch_report(PREV_YMD)
|
print('[fetch] report/v2/list T-1...'); rep=fetch_report(PREV_YMD)
|
||||||
|
except Exception as e:
|
||||||
|
src_status['report']='fail: '+str(e)[:120]
|
||||||
|
print('[ERROR] report/v2/list 拉取失败(可能MS token过期):', str(e)[:200])
|
||||||
|
|
||||||
|
# 两个源都失败 -> 放弃本次更新,不写 data.json
|
||||||
|
if src_status['superset'].startswith('fail') and src_status['report'].startswith('fail'):
|
||||||
|
print('[ABORT] 两个数据源都失败,本次不更新 data.json。')
|
||||||
|
print('!!! 需检查凭证: Superset cookie / MS token 可能均已过期 !!!')
|
||||||
|
import sys as _s; _s.exit(1)
|
||||||
|
# 单源失败:告警但继续(用另一个源的数据更新)
|
||||||
|
if src_status['report'].startswith('fail'):
|
||||||
|
print('!!!!! 告警: MS(report/v2/list) 数据源失效,本次 MS/带_API account 数据将缺失。请尽快更新 MS_TOKEN !!!!!')
|
||||||
|
if src_status['superset'].startswith('fail'):
|
||||||
|
print('!!!!! 告警: Superset 数据源失效,本次 Midas/无_API account 数据将缺失。请尽快更新 SUPERSET_COOKIE !!!!!')
|
||||||
|
|
||||||
# Superset: 只取 T-1 那天(dt格式20260910)
|
# Superset: 只取 T-1 那天(dt格式20260910)
|
||||||
sup_prev=[r for r in sup if str(r.get('dt'))==PREV_YMD]
|
sup_prev=[r for r in sup if str(r.get('dt'))==PREV_YMD]
|
||||||
@@ -277,6 +299,7 @@ for key in ['pkg_midas','pkg_ms','cust_daily','cust_detail']:
|
|||||||
old[key]=keep_recent(old[key])
|
old[key]=keep_recent(old[key])
|
||||||
|
|
||||||
old['updated_at']=datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=8))).strftime('%Y-%m-%d %H:%M:%S UTC+8')
|
old['updated_at']=datetime.datetime.now(datetime.timezone(datetime.timedelta(hours=8))).strftime('%Y-%m-%d %H:%M:%S UTC+8')
|
||||||
|
old['source_status']=src_status
|
||||||
json.dump(old,open(DATA_FILE,'w',encoding='utf-8'),ensure_ascii=False,separators=(',',':'))
|
json.dump(old,open(DATA_FILE,'w',encoding='utf-8'),ensure_ascii=False,separators=(',',':'))
|
||||||
print(f"[done] overall={len(old['overall'])}天 CN合计={cn_row['DSP CN revenue']} Intl合计={intl_row['DSP international']}")
|
print(f"[done] overall={len(old['overall'])}天 CN合计={cn_row['DSP CN revenue']} Intl合计={intl_row['DSP international']}")
|
||||||
print(f" pkg_midas={len(pkg_midas)}个pkg pkg_ms={len(pkg_ms)}个pkg cust分类={cust_cat_today}")
|
print(f" pkg_midas={len(pkg_midas)}个pkg pkg_ms={len(pkg_ms)}个pkg cust分类={cust_cat_today}")
|
||||||
|
|||||||
Reference in New Issue
Block a user