Commit 183cc78d by trace

日报添加下线统计

parent 949549d4
...@@ -22,20 +22,20 @@ let sleepTime = isTest() && (sec * 2) || (sec * 5) // 每个请求间隔5秒 ...@@ -22,20 +22,20 @@ let sleepTime = isTest() && (sec * 2) || (sec * 5) // 每个请求间隔5秒
let requestTimeout = sec * 20 let requestTimeout = sec * 20
let requestTopAppNum = isTest() && 1 || 100 let requestTopAppNum = isTest() && 1 || 100
let aliveTime = 9 // 多少点后开始发送邮件 let aliveTime = 9 // 多少点后开始发送邮件
let theDaySendList = [1,2,3,4,5,6,7] // 发送列表的时间(周几) let theDaySendList = [1, 2, 3, 4, 5, 6, 7] // 发送列表的时间(周几)
let aliveInterval = isTest() && 0.1 || 3 // 发送邮件间隔时间 let aliveInterval = isTest() && 0.1 || 3 // 发送邮件间隔时间
let start = true // 是否开始爬取监控 let start = true // 是否开始爬取监控
let dailyOnlineStartHours = 7 let dailyOnlineStartHours = 7
let dailyOnlineEndHours = 9 let dailyOnlineEndHours = 9
let crabName = `东南亚现金贷App监控${isTest() && '(Test)' || ''}` let crabName = `东南亚现金贷App监控${isTest() && '(Test)' || ''}`
let monitorRegion = {'vn': '越南', 'ph': '菲律宾', 'id': '印尼'} let monitorRegion = { 'vn': '越南', 'ph': '菲律宾', 'id': '印尼' }
let monitorType = {'FINANCE': '财务'} let monitorType = { 'FINANCE': '财务' }
let statusFile = `${process.cwd()}/status.json` let statusFile = `${process.cwd()}/status.json`
let monitorApps = `${process.cwd()}/google-play-monitor-apps.json` let monitorApps = `${process.cwd()}/google-play-monitor-apps.json`
let base_gp_url = 'https://play.google.com/store/apps/details?id=' let base_gp_url = 'https://play.google.com/store/apps/details?id='
let developer =['yingchen.nong@starwin.com'] let developer = ['yingchen.nong@starwin.com']
let notifyEmail = developer let notifyEmail = developer
let daichaoApps = [] let daichaoApps = []
...@@ -50,7 +50,7 @@ let isTimeToAppendOurApp = (apps) => { ...@@ -50,7 +50,7 @@ let isTimeToAppendOurApp = (apps) => {
// 需求变更, 是首次加入判断超过12小时就监控, 非每次12小时 // 需求变更, 是首次加入判断超过12小时就监控, 非每次12小时
// 遍历所有自有 app, 看当前时间与加入时间, 超过12小时就加入返回list // 遍历所有自有 app, 看当前时间与加入时间, 超过12小时就加入返回list
let needMonitorApps = [] let needMonitorApps = []
for (let i in apps ) { for (let i in apps) {
let key = apps[i] let key = apps[i]
let timeIn = status[key] && status[key].timeIn let timeIn = status[key] && status[key].timeIn
if (!timeIn) { if (!timeIn) {
...@@ -69,26 +69,26 @@ let isTimeToAppendOurApp = (apps) => { ...@@ -69,26 +69,26 @@ let isTimeToAppendOurApp = (apps) => {
return needMonitorApps return needMonitorApps
} }
let allNames = names => { let allNames = names => {
let an = [] let an = []
Object.keys(names).forEach(key => { Object.keys(names).forEach(key => {
if (key == "ourApps") { if (key == "ourApps") {
// 返回需要监控的自有 app // 返回需要监控的自有 app
an = [...an, ...isTimeToAppendOurApp(names[key])] an = [...an, ...isTimeToAppendOurApp(names[key])]
} else { } else {
an = [...an, ...names[key]] an = [...an, ...names[key]]
} }
}) })
return Array.from(new Set(an)) return Array.from(new Set(an))
} }
function log(content) { function log(content) {
if (isTest()) { if (isTest()) {
console.log(`[${new Date().toLocaleString()}]: ${content}`) console.log(`[${new Date().toLocaleString()}]: ${content}`)
} }
} }
function isTest() { function isTest() {
let testName = ['taketrace'] let testName = ['taketrace']
return testName.includes(username) return testName.includes(username)
} }
// Code ------------------------------------------------------------ // Code ------------------------------------------------------------
// 状态记录 // 状态记录
...@@ -98,25 +98,25 @@ let isFirstRun = false ...@@ -98,25 +98,25 @@ let isFirstRun = false
// 获取记录上次状态得文件 // 获取记录上次状态得文件
try { try {
status = JSON.parse(fs.readFileSync(statusFile, 'utf-8')) status = JSON.parse(fs.readFileSync(statusFile, 'utf-8'))
isFirstRun = false isFirstRun = false
} catch (err) { } catch (err) {
isFirstRun = true isFirstRun = true
console.log(`状态文件不存在, 直接使用空的{}\n${err.toString()}`) console.log(`状态文件不存在, 直接使用空的{}\n${err.toString()}`)
} }
// 获取记录上次更新监控名得文件 // 获取记录上次更新监控名得文件
try { try {
let fileNames = JSON.parse(fs.readFileSync(monitorApps, 'utf-8')) let fileNames = JSON.parse(fs.readFileSync(monitorApps, 'utf-8'))
if (Array.isArray(fileNames)) { if (Array.isArray(fileNames)) {
monitorNames['vn'] = fileNames monitorNames['vn'] = fileNames
console.log('原来只记录数组形式, 现在变更为对象形式, 原数组放到vn数组中') console.log('原来只记录数组形式, 现在变更为对象形式, 原数组放到vn数组中')
} else { } else {
monitorNames = fileNames monitorNames = fileNames
} }
isFirstRun = false isFirstRun = false
} catch (err) { } catch (err) {
console.log(`监控列表文件不存在, 直接使用空的{}\n${err.toString()}`) console.log(`监控列表文件不存在, 直接使用空的{}\n${err.toString()}`)
} }
let newOnline = [] // 新上架 let newOnline = [] // 新上架
let newOffline = [] // 新下架 let newOffline = [] // 新下架
...@@ -156,14 +156,19 @@ async function startMonitor() { ...@@ -156,14 +156,19 @@ async function startMonitor() {
// 每日在线列表报告 // 每日在线列表报告
if (!isInTimeInRangeToday(dailyOnlineStartHours, dailyOnlineEndHours)) { if (!isInTimeInRangeToday(dailyOnlineStartHours, dailyOnlineEndHours)) {
log('今天不在时间段或者已发过当日在线 app 列表') log('今天不在时间段或者已发过当日在线 app 列表')
dingDing(`今天不在时间段或者已发过当日在线 app 列表\n time:${new Date().toLocaleTimeString}`)
return return
} }
let onlineApps = ourAppIds.filter(val => status[val] && status[val].status || false) let onlineApps = ourAppIds.filter(val => status[val] && status[val].status || false)
let offlineApps = ourAppIds.filter(val => !onlineApps.includes(val))
let daichaoOnlines = daichaoApps.filter(val => status[val] && status[val].status || false) let daichaoOnlines = daichaoApps.filter(val => status[val] && status[val].status || false)
let daichaoOfflines = daichaoApps.filter(val => !daichaoOnlines.includes(val))
let content = '' let content = ''
content += wrapSummary(`Gitlab 在线 app (${onlineApps.length}/${ourAppIds.length})`, onlineApps.map(val => link(val))) content += wrapSummary(`Gitlab 在线 app (${onlineApps.length}/${ourAppIds.length})`, onlineApps.map(val => link(val)))
content += wrapSummary(`Gitlab 下线 app (${offlineApps.length}/${ourAppIds.length})`, offlineApps.map(val => link(val)))
content += wrapSummary(`贷超在线 App (${daichaoOnlines.length}/${daichaoApps.length})`, daichaoOnlines.map(val => link(val))) content += wrapSummary(`贷超在线 App (${daichaoOnlines.length}/${daichaoApps.length})`, daichaoOnlines.map(val => link(val)))
content += wrapSummary(`贷超下线 App (${daichaoOfflines.length}/${daichaoApps.length})`, daichaoOfflines.map(val => link(val)))
sendEmail(content) sendEmail(content)
}) })
.then(() => { .then(() => {
...@@ -172,7 +177,7 @@ async function startMonitor() { ...@@ -172,7 +177,7 @@ async function startMonitor() {
fs.writeFileSync(statusFile, JSON.stringify(status)) fs.writeFileSync(statusFile, JSON.stringify(status))
log(`文件写入成功`) log(`文件写入成功`)
}) })
.then(() => log('over')) .then(() => log('over'))
.catch(err => { .catch(err => {
lastIntervalTime = lastIntervalTime * 2 lastIntervalTime = lastIntervalTime * 2
let content = `监控出错${err}\n间隔时间调整为${(lastIntervalTime) / minute}分钟` let content = `监控出错${err}\n间隔时间调整为${(lastIntervalTime) / minute}分钟`
...@@ -200,86 +205,86 @@ async function startMonitor() { ...@@ -200,86 +205,86 @@ async function startMonitor() {
} }
async function getDaichao() { async function getDaichao() {
await getPromiss(daichao) await getPromiss(daichao)
.then(val => { .then(val => {
if (isTest()) { if (isTest()) {
daichaoApps = [] daichaoApps = []
return
}
daichaoData = JSON.parse(val && val.body && val.body || "{}").data
daichaoApps = daichaoData && daichaoData.map(app => app.packageName) || []
log(`代超数据: ${daichaoApps.length} 个`)
monitorNames["daichao"] = daichaoApps
if (daichaoApps.length == 0) {
log('代超数据为空')
}
})
.catch(err => {
errorLog.push(`贷超获取失败:${err.toString()}`)
return return
} })
daichaoData = JSON.parse(val && val.body && val.body || "{}").data
daichaoApps = daichaoData && daichaoData.map(app => app.packageName) || []
log(`代超数据: ${daichaoApps.length} 个`)
monitorNames["daichao"] = daichaoApps
if (daichaoApps.length == 0) {
log('代超数据为空')
}
})
.catch(err => {
errorLog.push(`贷超获取失败:${err.toString()}`)
return
})
} }
async function getConfig() { async function getConfig() {
await getPromiss(subApi).then(val => { await getPromiss(subApi).then(val => {
log('------------ get congfig from gitlab -----------') log('------------ get congfig from gitlab -----------')
log(val.body) log(val.body)
let dataes = {} let dataes = {}
if (isTest()) { if (isTest()) {
try { try {
dataes = JSON.parse(val.body) dataes = JSON.parse(val.body)
} catch (err) { } catch (err) {
throw `哪位老哥, 配置文件写错了啊...>>>>>>>>>\n${err}\n<<<<<<<<<\n` throw `哪位老哥, 配置文件写错了啊...>>>>>>>>>\n${err}\n<<<<<<<<<\n`
} }
ourApps = dataes.ourApps || {} ourApps = dataes.ourApps || {}
ourAppIds = Object.keys(ourApps) ourAppIds = Object.keys(ourApps)
if (ourAppIds.length == 0) { if (ourAppIds.length == 0) {
ourApps = {"com.globe.gcash.android": "测试我的"} ourApps = { "com.globe.gcash.android": "测试我的" }
ourAppIds = ["com.globe.gcash.android"] ourAppIds = ["com.globe.gcash.android"]
} }
monitorNames["ourApps"] = ourAppIds monitorNames["ourApps"] = ourAppIds
ourAppIds.forEach(id => { ourAppIds.forEach(id => {
// 添加进状态文件, 设置上名字 (因为后面的能知道名字的操作只有获取前100的时候, 获取权限是不知道名字的) // 添加进状态文件, 设置上名字 (因为后面的能知道名字的操作只有获取前100的时候, 获取权限是不知道名字的)
status[id] = {...(status[id] || {}), appName: ourApps[id]} status[id] = { ...(status[id] || {}), appName: ourApps[id] }
if (!status[id].timeIn) { if (!status[id].timeIn) {
// 如果没有记录加入时间, 记录, 加入时间只记录一次, 在 isTimeToAppendOurApp 中判断记录时间, 超过12小时就开始监控 // 如果没有记录加入时间, 记录, 加入时间只记录一次, 在 isTimeToAppendOurApp 中判断记录时间, 超过12小时就开始监控
status[id] = { ...status[id], timeIn: Date() } status[id] = { ...status[id], timeIn: Date() }
} }
}) })
} else { } else {
dataes = JSON.parse(val.body) dataes = JSON.parse(val.body)
let config = dataes.config let config = dataes.config
let subscriber = dataes.subscriber let subscriber = dataes.subscriber
ourApps = dataes.ourApps || {} ourApps = dataes.ourApps || {}
ourAppIds = Object.keys(ourApps) ourAppIds = Object.keys(ourApps)
monitorNames["ourApps"] = ourAppIds monitorNames["ourApps"] = ourAppIds
ourAppIds.forEach(id => { ourAppIds.forEach(id => {
// 添加进状态文件, 设置上名字 (因为后面的能知道名字的操作只有获取前100的时候, 获取权限是不知道名字的) // 添加进状态文件, 设置上名字 (因为后面的能知道名字的操作只有获取前100的时候, 获取权限是不知道名字的)
status[id] = {...(status[id] || {}), appName: ourApps[id]} status[id] = { ...(status[id] || {}), appName: ourApps[id] }
if (!status[id].timeIn) { if (!status[id].timeIn) {
// 如果没有记录加入时间, 记录, 加入时间只记录一次, 在 isTimeToAppendOurApp 中判断记录时间, 超过12小时就开始监控 // 如果没有记录加入时间, 记录, 加入时间只记录一次, 在 isTimeToAppendOurApp 中判断记录时间, 超过12小时就开始监控
status[id] = {...status[id], timeIn: Date()} status[id] = { ...status[id], timeIn: Date() }
} }
}) })
// 订阅人 // 订阅人
notifyEmail = subscriber && Object.keys(subscriber) || notifyEmail notifyEmail = subscriber && Object.keys(subscriber) || notifyEmail
// 配置更新 // 配置更新
defaultIntervalTime = minute * (config.defaultIntervalTime || defaultIntervalTime) defaultIntervalTime = minute * (config.defaultIntervalTime || defaultIntervalTime)
sleepTime = sec * (config.sleepTime || sleepTime) sleepTime = sec * (config.sleepTime || sleepTime)
requestTimeout = sec * (config.requestTimeout || requestTimeout) requestTimeout = sec * (config.requestTimeout || requestTimeout)
requestTopAppNum = config.requestTopAppNum || requestTopAppNum requestTopAppNum = config.requestTopAppNum || requestTopAppNum
aliveTime = config.aliveTime || aliveTime aliveTime = config.aliveTime || aliveTime
if (Array.isArray(config.theDaySendList)) { if (Array.isArray(config.theDaySendList)) {
theDaySendList = config.theDaySendList theDaySendList = config.theDaySendList
} else { } else {
theDaySendList = config.theDaySendList && [config.theDaySendList] || theDaySendList theDaySendList = config.theDaySendList && [config.theDaySendList] || theDaySendList
} }
aliveInterval = config.aliveInterval || aliveInterval aliveInterval = config.aliveInterval || aliveInterval
crabName = config.crabName || crabName crabName = config.crabName || crabName
monitorRegion = config.monitorRegion || monitorRegion monitorRegion = config.monitorRegion || monitorRegion
monitorType = config.monitorType || monitorType monitorType = config.monitorType || monitorType
base_gp_url = config.base_gp_url || base_gp_url base_gp_url = config.base_gp_url || base_gp_url
...@@ -287,16 +292,16 @@ async function getConfig() { ...@@ -287,16 +292,16 @@ async function getConfig() {
start = config.start || start start = config.start || start
dailyOnlineStartHours = config.dailyOnlineStartHours || dailyOnlineStartHours dailyOnlineStartHours = config.dailyOnlineStartHours || dailyOnlineStartHours
dailyOnlineEndHours = config.dailyOnlineEndHours || dailyOnlineEndHours dailyOnlineEndHours = config.dailyOnlineEndHours || dailyOnlineEndHours
log(JSON.stringify(config)) log(JSON.stringify(config))
log(JSON.stringify(notifyEmail)) log(JSON.stringify(notifyEmail))
} }
}) })
} }
async function getTop100() { async function getTop100() {
log(`获取以下国家前${requestTopAppNum}: ${JSON.stringify(monitorRegion)}`) log(`获取以下国家前${requestTopAppNum}: ${JSON.stringify(monitorRegion)}`)
let regions = Object.keys(monitorRegion) let regions = Object.keys(monitorRegion)
let types = Object.keys(monitorType) let types = Object.keys(monitorType)
for (let i in regions) { for (let i in regions) {
let region = regions[i] let region = regions[i]
log(`地区: ${region}`) log(`地区: ${region}`)
names = monitorNames[region] || [] names = monitorNames[region] || []
...@@ -305,7 +310,7 @@ async function getTop100() { ...@@ -305,7 +310,7 @@ async function getTop100() {
let type = types[t] let type = types[t]
log(`分类: ${type}`) log(`分类: ${type}`)
// 数量分页 // 数量分页
let getTimes = Math.floor(requestTopAppNum/120) + 1 let getTimes = Math.floor(requestTopAppNum / 120) + 1
let lastGetNum = requestTopAppNum % 120 let lastGetNum = requestTopAppNum % 120
if (getTimes > 5) { if (getTimes > 5) {
if (getTimes > 6) { if (getTimes > 6) {
...@@ -328,7 +333,7 @@ async function getTop100() { ...@@ -328,7 +333,7 @@ async function getTop100() {
requestOptions: { timeout: requestTimeout } requestOptions: { timeout: requestTimeout }
}) })
.then(res => { .then(res => {
console.log(`获取到 <${monitorRegion[region]}>[${monitorType[type]}]排名: ${i*120} ~ ${i*120+getNum}`) console.log(`获取到 <${monitorRegion[region]}>[${monitorType[type]}]排名: ${i * 120} ~ ${i * 120 + getNum}`)
if (res && res.length && res.length > 0) { if (res && res.length && res.length > 0) {
res.forEach(app => { res.forEach(app => {
...@@ -356,7 +361,7 @@ async function getTop100() { ...@@ -356,7 +361,7 @@ async function getTop100() {
newTopMonitorNames[region] = [...(newTopMonitorNames[region] && newTopMonitorNames[region] || []), ...newForRegion] newTopMonitorNames[region] = [...(newTopMonitorNames[region] && newTopMonitorNames[region] || []), ...newForRegion]
monitorNames[region] = names monitorNames[region] = names
} }
} }
} }
...@@ -403,7 +408,7 @@ async function monitorIfOnline(names) { ...@@ -403,7 +408,7 @@ async function monitorIfOnline(names) {
function link(name, countOurs) { function link(name, countOurs) {
let ourName = isOurs(name, countOurs) let ourName = isOurs(name, countOurs)
return `${ourName} return `${ourName}
<a href="${base_gp_url}${name}"> <a href="${base_gp_url}${name}">
${getRegion(name)}[${monitorType[status[name] && status[name].category || ''] || ''}] - ${name} ${getRegion(name)}[${monitorType[status[name] && status[name].category || ''] || ''}] - ${name}
<br/> <br/>
...@@ -411,66 +416,66 @@ function link(name, countOurs) { ...@@ -411,66 +416,66 @@ function link(name, countOurs) {
</a>` </a>`
} }
function getRegion(name) { function getRegion(name) {
let regions = Object.keys(monitorNames) let regions = Object.keys(monitorNames)
for (let i in regions) { for (let i in regions) {
let key = regions[i] let key = regions[i]
if (monitorNames[key].includes(name)) { if (monitorNames[key].includes(name)) {
return monitorRegion[key] || key return monitorRegion[key] || key
} }
} }
} }
function markError() { function markError() {
let emailContent = '' let emailContent = ''
log(`发生意外错误, 生错错误邮件: ${errorLog.toString()}`) log(`发生意外错误, 生错错误邮件: ${errorLog.toString()}`)
emailContent += `<details>` emailContent += `<details>`
emailContent += `<summary>虫子拿权限发生意外事故</summary>` emailContent += `<summary>虫子拿权限发生意外事故</summary>`
emailContent += `<dl>` emailContent += `<dl>`
errorLog.forEach(e => { errorLog.forEach(e => {
emailContent += `<dt>${e}</dt>` emailContent += `<dt>${e}</dt>`
}) })
emailContent += `</dl>` emailContent += `</dl>`
emailContent += `</details>` emailContent += `</details>`
errorLog = [] errorLog = []
return emailContent return emailContent
} }
function genMail() { function genMail() {
let firstLine = '' // 第一行不用打开邮箱就能显示, 用来展示关键信息 let firstLine = '' // 第一行不用打开邮箱就能显示, 用来展示关键信息
let emailContent = '' let emailContent = ''
let lastSendListDate = new Date(status.sendListDate || 'Tue Jan 29 2019 19:32:24 GMT+0800 (CST)') let lastSendListDate = new Date(status.sendListDate || 'Tue Jan 29 2019 19:32:24 GMT+0800 (CST)')
let today = new Date() let today = new Date()
let needSendList = (theDaySendList.includes(today.getDay())) && (lastSendListDate.toLocaleDateString() != today.toLocaleDateString()) let needSendList = (theDaySendList.includes(today.getDay())) && (lastSendListDate.toLocaleDateString() != today.toLocaleDateString())
if (!isFirstRun if (!isFirstRun
&& !needSendList && !needSendList
&& newOffline.length == 0 && newOffline.length == 0
&& newOnline.length == 0 && newOnline.length == 0
&& Object.keys(permissionChange).length == 0 && Object.keys(permissionChange).length == 0
&& Object.keys(newTopMonitorNames).length == 0) { && Object.keys(newTopMonitorNames).length == 0) {
log(`没有更新, 不生成内容邮件`) log(`没有更新, 不生成内容邮件`)
if (errorLog.length > 0) { if (errorLog.length > 0) {
emailContent += `Error: ${markError()}` emailContent += `Error: ${markError()}`
return emailContent return emailContent
} }
return null return null
} }
log(`第一次跑: ${isFirstRun}, 新下: ${newOffline.length}, 新上: ${newOnline.length}, 权限改变: ${Object.keys(permissionChange).length}`) log(`第一次跑: ${isFirstRun}, 新下: ${newOffline.length}, 新上: ${newOnline.length}, 权限改变: ${Object.keys(permissionChange).length}`)
if (errorLog.length > 0) { if (errorLog.length > 0) {
emailContent += markError() emailContent += markError()
} }
if (failedApps.length > 0 && isFirstRun) { if (failedApps.length > 0 && isFirstRun) {
emailContent += `<div>本次第一次监控</div>` emailContent += `<div>本次第一次监控</div>`
failedApps.forEach(name => { failedApps.forEach(name => {
emailContent += `<div>获取失败}: ${link(name, true)} </div>` emailContent += `<div>获取失败}: ${link(name, true)} </div>`
}) })
} }
if (isFirstRun) { if (isFirstRun) {
isFirstRun = false isFirstRun = false
} }
if (daichaoApps.length == 0) { if (daichaoApps.length == 0) {
emailContent += '<div>没有从贷超监控中获取数据</div>' emailContent += '<div>没有从贷超监控中获取数据</div>'
} }
// --------- 判断上下线和进入 top 中我们 app 的数量 // --------- 判断上下线和进入 top 中我们 app 的数量
...@@ -487,19 +492,19 @@ function genMail() { ...@@ -487,19 +492,19 @@ function genMail() {
// --------- 判断上下线和进入 top 中我们 app 的数量 // --------- 判断上下线和进入 top 中我们 app 的数量
if (Object.keys(newTopMonitorNames).length > 0) { if (Object.keys(newTopMonitorNames).length > 0) {
emailContent += `<div>------------从${Object.keys(newTopMonitorNames).length}个国家新增监控:-----------</div>` emailContent += `<div>------------从${Object.keys(newTopMonitorNames).length}个国家新增监控:-----------</div>`
Object.keys(newTopMonitorNames).forEach(key => { Object.keys(newTopMonitorNames).forEach(key => {
let names = newTopMonitorNames[key] let names = newTopMonitorNames[key]
if (names.length > 0) { if (names.length > 0) {
// 判断每个国家新增里自己的 app, 累加 // 判断每个国家新增里自己的 app, 累加
ourTop = [...ourTop, ...ourAppIds.filter(val => names.includes(val))] ourTop = [...ourTop, ...ourAppIds.filter(val => names.includes(val))]
daichaoTop = [...daichaoTop, ...daichaoApps.filter(val => names.includes(val))] daichaoTop = [...daichaoTop, ...daichaoApps.filter(val => names.includes(val))]
emailContent += wrapSummary(`本次从<${monitorRegion[key]}>top${requestTopAppNum}新增监控: ${names.length} 个`, emailContent += wrapSummary(`本次从<${monitorRegion[key]}>top${requestTopAppNum}新增监控: ${names.length} 个`,
names.map(n => `${link(n.id, true)}进top100`)) names.map(n => `${link(n.id, true)}进top100`))
} }
}) })
emailContent += `<br/>/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>` emailContent += `<br/>/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>`
} }
// 自己 app // 自己 app
firstLine = `《${firstLine}${ourUp.length > 0 ? `上${ourUp.length}` : ''}` firstLine = `《${firstLine}${ourUp.length > 0 ? `上${ourUp.length}` : ''}`
...@@ -514,270 +519,271 @@ function genMail() { ...@@ -514,270 +519,271 @@ function genMail() {
hitOurs = ourUp.length + ourDown.length + ourTop.length hitOurs = ourUp.length + ourDown.length + ourTop.length
hitDaichao = daichaoUp.length + daichaoDown.length + daichaoTop.length hitDaichao = daichaoUp.length + daichaoDown.length + daichaoTop.length
if (newOffline.length == 0) { if (newOffline.length == 0) {
emailContent += '<div>没有登记中的产品被新下架</div>' emailContent += '<div>没有登记中的产品被新下架</div>'
} else { } else {
emailContent += `<br/>------------新下架: ${newOffline.length} 个-----------<br/>` emailContent += `<br/>------------新下架: ${newOffline.length} 个-----------<br/>`
newOffline.forEach(name => { newOffline.forEach(name => {
let his = (status[name] && status[name].permissionHis && status[name].permissionHis) || {} let his = (status[name] && status[name].permissionHis && status[name].permissionHis) || {}
his.lastPermissions = (status[name] && status[name].permissions && status[name].permissions) || [] his.lastPermissions = (status[name] && status[name].permissions && status[name].permissions) || []
emailContent += getPermissionChangeContent(name, his, `新下架ಥ_ಥ(及上次权限情况)`) emailContent += getPermissionChangeContent(name, his, `新下架ಥ_ಥ(及上次权限情况)`)
// emailContent += `<div>检测到新下架ಥ_ಥ: ${link(name)}</div>` // emailContent += `<div>检测到新下架ಥ_ಥ: ${link(name)}</div>`
}) })
emailContent += `<br/>/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>` emailContent += `<br/>/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>`
} }
if (newOnline.length == 0) { if (newOnline.length == 0) {
emailContent += `<div>没有登记中的产品新上架</div>` emailContent += `<div>没有登记中的产品新上架</div>`
} else { } else {
emailContent += `<div>-----------新上架: ${newOnline.length} 个---------------------</div>` emailContent += `<div>-----------新上架: ${newOnline.length} 个---------------------</div>`
newOnline.forEach(name => { newOnline.forEach(name => {
if (permissionChange[name]) { if (permissionChange[name]) {
emailContent += getPermissionChangeContent(name, permissionChange[name], `新上架😃: `) emailContent += getPermissionChangeContent(name, permissionChange[name], `新上架😃: `)
emailContent += `<br/>/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>` emailContent += `<br/>/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>`
delete permissionChange[name] delete permissionChange[name]
} else { } else {
emailContent += wrapSummary(`<div>新上架^_^: ${link(name, true)}</div>`, emailContent += wrapSummary(`<div>新上架^_^: ${link(name, true)}</div>`,
((status[name] && status[name].permissions && status[name].permissions) || [])) ((status[name] && status[name].permissions && status[name].permissions) || []))
emailContent += `<br/>/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>` emailContent += `<br/>/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>`
} }
}) })
} }
if (Object.keys(permissionChange).length == 0) { if (Object.keys(permissionChange).length == 0) {
emailContent += `<div>没有检测到有产品仅权限改变</div>` emailContent += `<div>没有检测到有产品仅权限改变</div>`
} else { } else {
log('监测到有权限改变') log('监测到有权限改变')
emailContent += `<br/>---------------权限改变: ${Object.keys(permissionChange).length} 个-------------<br/>` emailContent += `<br/>---------------权限改变: ${Object.keys(permissionChange).length} 个-------------<br/>`
Object.keys(permissionChange).forEach(val => { Object.keys(permissionChange).forEach(val => {
emailContent += getPermissionChangeContent(val, permissionChange[val]) emailContent += getPermissionChangeContent(val, permissionChange[val])
}) })
emailContent += `<br/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>` emailContent += `<br/>^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br/>`
} }
// 发送当前监控列表 // 发送当前监控列表
if (needSendList) { if (needSendList) {
emailContent += `<br/><br/><br/>` emailContent += `<br/><br/><br/>`
let countrys = Object.keys(monitorRegion) let countrys = Object.keys(monitorRegion)
monitorRegion monitorRegion
emailContent += `<div>下面是监控列表<br/>当前监控${countrys.length}个国家</div>` emailContent += `<div>下面是监控列表<br/>当前监控${countrys.length}个国家</div>`
let total = 0 let total = 0
Object.keys(monitorNames).forEach(val => { Object.keys(monitorNames).forEach(val => {
let num = monitorNames[val].length let num = monitorNames[val].length
total += num total += num
emailContent += wrapSummary(`${monitorRegion[val] || val}(${num}个)`, monitorNames[val].map(id => link(id, false))) emailContent += wrapSummary(`${monitorRegion[val] || val}(${num}个)`, monitorNames[val].map(id => link(id, false)))
}) })
emailContent += `<div>监控总数量: ${total}</div>` emailContent += `<div>监控总数量: ${total}</div>`
status.sendListDate = today.toString() status.sendListDate = today.toString()
} }
emailContent += `<br/><br/><br/>${new Date().toLocaleString()}` emailContent += `<br/><br/><br/>${new Date().toLocaleString()}`
log(`生成邮件内容: \n${emailContent}`) log(`生成邮件内容: \n${emailContent}`)
// 清空临时栈 // 清空临时栈
newOffline = [] newOffline = []
newOnline = [] newOnline = []
permissionChange = {} permissionChange = {}
failedApps = [] failedApps = []
errorLog = [] errorLog = []
newTopMonitorNames = {} newTopMonitorNames = {}
return `<div>${firstLine}</div><br/>${emailContent}` return `<div>${firstLine}</div><br/>${emailContent}`
} }
function isOurs(name, countOurs) { function isOurs(name, countOurs) {
if (daichaoApps.includes(name)) { if (daichaoApps.includes(name)) {
return "🏦(贷超)" return "🏦(贷超)"
} }
if (ourAppIds.includes(name)) { if (ourAppIds.includes(name)) {
return `📌(${ourApps[name] || 'No Name in Gitlab'})` return `📌(${ourApps[name] || 'No Name in Gitlab'})`
} }
return '' return ''
} }
function getPermissionChangeContent(id, obj, title) { function getPermissionChangeContent(id, obj, title) {
changes = [] changes = []
if (obj.adds && obj.adds.length > 0) { changes.push(wrapSummary(`添加`, obj.adds, "green")) } if (obj.adds && obj.adds.length > 0) { changes.push(wrapSummary(`添加`, obj.adds, "green")) }
if (obj.deletes && obj.deletes.length > 0) { changes.push(wrapSummary(`删除`, obj.deletes, "red")) } if (obj.deletes && obj.deletes.length > 0) { changes.push(wrapSummary(`删除`, obj.deletes, "red")) }
if (obj.stills && obj.stills.length > 0) { changes.push(wrapSummary(`保留`, obj.stills, "gray")) } if (obj.stills && obj.stills.length > 0) { changes.push(wrapSummary(`保留`, obj.stills, "gray")) }
if (obj.newPermission && obj.newPermission.length > 0) { changes.push(wrapSummary(`新权限`, obj.newPermission)) } if (obj.newPermission && obj.newPermission.length > 0) { changes.push(wrapSummary(`新权限`, obj.newPermission)) }
if (obj.lastPermissions && obj.lastPermissions.length > 0) { changes.push(wrapSummary(`旧权限`, obj.lastPermissions)) } if (obj.lastPermissions && obj.lastPermissions.length > 0) { changes.push(wrapSummary(`旧权限`, obj.lastPermissions)) }
log(`权限改变: ${id}: ${changes.length}`) log(`权限改变: ${id}: ${changes.length}`)
return wrapSummary(`- <div>${title || '权限改变'}:<br/>${link(id, true)}</div>`, changes) return wrapSummary(`- <div>${title || '权限改变'}:<br/>${link(id, true)}</div>`, changes)
} }
function setPermissionHis(name, obj) { function setPermissionHis(name, obj) {
status[name].permissionHis = {adds: obj.adds, deletes: obj.deletes, stills: obj.stills} status[name].permissionHis = { adds: obj.adds, deletes: obj.deletes, stills: obj.stills }
} }
function aliveContent(date, lastSend) { function aliveContent(date, lastSend) {
let emailContent = '' let emailContent = ''
emailContent += `<div>现在是: ${date.toLocaleString()}, 监控还活着</div>` emailContent += `<div>现在是: ${date.toLocaleString()}, 监控还活着</div>`
let allN = allNames(monitorNames).length let allN = allNames(monitorNames).length
emailContent += `<div>当前总监控: ${allN}, \n设置间隔时间: ${( lastIntervalTime / minute)}\n上次记录存活时间: ${lastSend.toLocaleString()}</div>` emailContent += `<div>当前总监控: ${allN}, \n设置间隔时间: ${(lastIntervalTime / minute)}\n上次记录存活时间: ${lastSend.toLocaleString()}</div>`
log(emailContent) log(emailContent)
return emailContent return emailContent
} }
function sendEmail(content, to = notifyEmail) { function sendEmail(content, to = notifyEmail) {
if (content == null || content == undefined || content == '') { if (content == null || content == undefined || content == '') {
console.log('没有生成内容, 检查心跳') console.log('没有生成内容, 检查心跳')
let date = new Date() let date = new Date()
let lastDing = new Date(status.lastDingDate || 'Tue Jan 29 2019 19:32:24 GMT+0800 (CST)') let lastDing = new Date(status.lastDingDate || 'Tue Jan 29 2019 19:32:24 GMT+0800 (CST)')
let lastSend = new Date(status.lastSendDate || 'Tue Jan 29 2019 19:32:24 GMT+0800 (CST)') let lastSend = new Date(status.lastSendDate || 'Tue Jan 29 2019 19:32:24 GMT+0800 (CST)')
if ((date.getHours() - lastDing.getHours()) >= aliveInterval) { if ((date.getHours() - lastDing.getHours()) >= aliveInterval) {
log('钉钉发送心跳') log('钉钉发送心跳')
dingDing(aliveContent(date, lastDing)) dingDing(aliveContent(date, lastDing))
status['lastDingDate'] = date.toString() status['lastDingDate'] = date.toString()
} }
if (date.toLocaleDateString() != lastSend.toLocaleDateString()) { if (date.toLocaleDateString() != lastSend.toLocaleDateString()) {
// 不是同一天, 且是9点, 发送, 发送后重新保存发送时间为当天, 当天的就不会发送是否还活着 // 不是同一天, 且是9点, 发送, 发送后重新保存发送时间为当天, 当天的就不会发送是否还活着
log(`当前时间: ${date.toLocaleString()}, 上次存活提示时间: ${lastSend.toLocaleString()}`) log(`当前时间: ${date.toLocaleString()}, 上次存活提示时间: ${lastSend.toLocaleString()}`)
if (date.getHours() > aliveTime) { if (date.getHours() > aliveTime) {
log(`发送心跳`) log(`发送心跳`)
content = aliveContent(date, lastSend) content = aliveContent(date, lastSend)
status['lastSendDate'] = date.toString() status['lastSendDate'] = date.toString()
} else { } else {
return return
} }
} else { } else {
return return
} }
return return
} }
console.log(`发送email: ${content.length}`) console.log(`发送email: ${content.length}`)
if (content.indexOf('Error') != -1) { if (content.indexOf('Error') != -1) {
to = developer to = developer
} else { } else {
// to = [...to, 添加只对自己app监控的人] // to = [...to, 添加只对自己app监控的人]
} }
let myEmail = 'chaolun.ni@starwin.com' let myEmail = 'chaolun.ni@starwin.com'
let emailTo = to.join(', ') let emailTo = to.join(', ')
let trans = nodemailer.createTransport({ let trans = nodemailer.createTransport({
host: 'smtp.exmail.qq.com', host: 'smtp.exmail.qq.com',
port: 587, port: 587,
secure: false, secure: false,
auth: { auth: {
user: myEmail, user: myEmail,
pass: '3JkTpbNQ3DeNRJbu' pass: '3JkTpbNQ3DeNRJbu'
} }
}) })
let appendTitle = hitOurs > 0 ? `📌${hitOurs}` : '' let appendTitle = hitOurs > 0 ? `📌${hitOurs}` : ''
appendTitle = hitDaichao > 0 ? `${appendTitle}🏦${hitDaichao}` : `${appendTitle}` appendTitle = hitDaichao > 0 ? `${appendTitle}🏦${hitDaichao}` : `${appendTitle}`
let mailOption = { let mailOption = {
from: myEmail, from: myEmail,
to: emailTo, to: emailTo,
subject: `${appendTitle}.${crabName}`, subject: `${appendTitle}.${crabName}`,
text: content, text: content,
html: content, html: content,
} }
trans.sendMail(mailOption, (error, info) => { trans.sendMail(mailOption, (error, info) => {
if (error) { if (error) {
return console.log(`发生错误: ${error}`); return console.log(`发生错误: ${error}`);
} }
console.log(`message ${info.messageId} send: ${info.response}`) console.log(`message ${info.messageId} send: ${info.response}`)
}) })
dingDing(content, notifyDingding) dingDing(content, notifyDingding)
// 清空计数 // 清空计数
hitDaichao = 0 hitDaichao = 0
hitOurs = 0 hitOurs = 0
} }
function dingDing(content, toDing=debugDingding) { function dingDing(content, toDing = debugDingding) {
log(`发送钉钉~`) log(`发送钉钉~`)
content = `${crabName}\n` + content content = `${crabName}\n` + content
request.post(toDing, { request.post(toDing, {
headers: { 'content-type': 'application/json;charset=utf-8'}, headers: { 'content-type': 'application/json;charset=utf-8' },
body: JSON.stringify({ body: JSON.stringify({
msgtype: 'text', msgtype: 'text',
text: {content: content} text: { content: content }
}) })
}, (err, param) => param.statusCode != 200 && log(`Error:${err}\nParam: ${JSON.stringify(param)}`)) }, (err, param) => param.statusCode != 200 && log(`Error:${err}\nParam: ${JSON.stringify(param)}`))
} }
function sleep(ms) { function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms)); return new Promise(resolve => setTimeout(resolve, ms));
} }
function judgeNewOnline(name) { function judgeNewOnline(name) {
if (status[name] && status[name].status == false) { if (status[name] && status[name].status == false) {
log(`${name} 新上架 😃`) log(`${name} 新上架 😃`)
newOnline.push(name) newOnline.push(name)
} }
} }
function judgeNewOffline(name) { function judgeNewOffline(name) {
if (status[name] && status[name].status == true) { if (status[name] && status[name].status == true) {
log(`${name} 被下架了 ಥ_ಥ`) log(`${name} 被下架了 ಥ_ಥ`)
newOffline.push(name) newOffline.push(name)
} }
} }
function judgePermissionChanged(name, newPermission) { function judgePermissionChanged(name, newPermission) {
log(`检查${name}权限是否变化`) log(`检查${name}权限是否变化`)
if (status[name] == undefined || status[name].permissions == undefined) { if (status[name] == undefined || status[name].permissions == undefined) {
log(`拿不到这个名字${name}记录, 不做权限变化检测了`) log(`拿不到这个名字${name}记录, 不做权限变化检测了`)
return return
} }
let oldPermissions = (status[name] && status[name].permissions && status[name].permissions) || [] let oldPermissions = (status[name] && status[name].permissions && status[name].permissions) || []
let oldPSet = new Set(oldPermissions) let oldPSet = new Set(oldPermissions)
let newPSet = new Set(newPermission || []) let newPSet = new Set(newPermission || [])
let deletes = new Set([...oldPSet].filter(x => !newPSet.has(x))) let deletes = new Set([...oldPSet].filter(x => !newPSet.has(x)))
let adds = new Set([...newPSet].filter(x => !oldPSet.has(x))) let adds = new Set([...newPSet].filter(x => !oldPSet.has(x)))
let stills = new Set([...oldPSet].filter(x => newPSet.has(x))) let stills = new Set([...oldPSet].filter(x => newPSet.has(x)))
let situation = { let situation = {
adds: Array.from(adds), adds: Array.from(adds),
deletes: Array.from(deletes), deletes: Array.from(deletes),
stills: Array.from(stills), stills: Array.from(stills),
} }
if (oldPermissions.length != newPermission.length) { if (oldPermissions.length != newPermission.length) {
log(`${name} 有权限改变`) log(`${name} 有权限改变`)
permissionChange[name] = { permissionChange[name] = {
name: name, name: name,
newPermission: newPermission, newPermission: newPermission,
lastPermissions: oldPermissions, lastPermissions: oldPermissions,
...situation, ...situation,
} }
setPermissionHis(name, situation) setPermissionHis(name, situation)
return return
} }
if (deletes.size > 0 || adds.size > 0) { if (deletes.size > 0 || adds.size > 0) {
log(`${name} 有权限改变`) log(`${name} 有权限改变`)
permissionChange[name] = { permissionChange[name] = {
name: name, name: name,
newPermission: newPermission, newPermission: newPermission,
lastPermissions: oldPermissions, lastPermissions: oldPermissions,
...situation, ...situation,
} }
setPermissionHis(name, situation) setPermissionHis(name, situation)
} }
} }
function wrapSummary(title, list, color='black') { function wrapSummary(title, list, color = 'black') {
let emailContent = '' let emailContent = ''
emailContent += `<details style="color:${color}">` emailContent += `<details style="color:${color}">`
emailContent += `<summary>${title}: </summary>` emailContent += `<summary>${title}: </summary>`
emailContent += `<dl>` emailContent += `<dl>`
list.forEach(l => { list.forEach(l => {
emailContent += `<dt>- ${l}</dt>` emailContent += `<dt>- ${l}</dt>`
}) })
emailContent += `</dl>` emailContent += `</dl>`
emailContent += `</details>` emailContent += `</details>`
return emailContent return emailContent
} }
function isInTimeInRangeToday(start, end) { function isInTimeInRangeToday(start, end) {
let dayKey = "lastDailyOnlinesAppsDate" let dayKey = "lastDailyOnlinesAppsDate"
let now = new Date() let now = new Date()
let lastDate = new Date(status[dayKey] || 'Tue Jan 29 2019 19:32:24 GMT+0800 (CST)') let lastDate = new Date(status[dayKey] || 'Tue Jan 29 2019 19:32:24 GMT+0800 (CST)')
lastDate.setHours(lastDate.getHours() + 24) lastDate.setHours(lastDate.getHours() + 24)
if (start < now.getHours() && now.getHours() < end && now > lastDate) { // 去掉范围的验证, 只要大于某一时间就发, 且只发一次
status[dayKey] = Date() if (start < now.getHours() && now > lastDate) {
return true status[dayKey] = Date()
} return true
}
return false return false
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment